Example #1
0
        static public bool consume(ClassParseReader reader, ClassString st)
        {
            int count = st.data.Length;

            if (count > reader.property_remaining)
            {
                return(false);
            }

            String data1 = st.data;

            char[] data2 = reader.property_data;
            int    i1    = count;
            int    i2    = reader.property_pos + count;

            while (i1 > 0)
            {
                if (data1[--i1] != data2[--i2])
                {
                    return(false);
                }
            }

            reader.property_pos       += count;
            reader.property_column    += count;
            reader.property_remaining -= count;
            return(true);
        }
Example #2
0
        // Group: Functions
        // __________________________________________________________________________


        /* Constructor: Class
         *
         * Creates a new class topic page.  Which features are available depend on which parameters you pass.
         *
         * - If you pass a <ClassString> AND a class ID, all features are available immediately.
         * - If you only pass a <ClassString>, then only the <path properties> are available.
         * - If you only pass a class ID, then only the <database functions> are available.
         *		- The <path properties> will be available after one of the <database functions> is called as they will look up the
         *			<ClassString>.
         *		- It is safe to call <HTMLTopicPage.Build()> when you only passed a class ID.
         */
        public Class(Builders.HTML htmlBuilder, int classID = 0, ClassString classString = default(ClassString)) : base(htmlBuilder)
        {
            // DEPENDENCY: This class assumes HTMLTopicPage.Build() will call a database function before using any path properties.

            this.classID     = classID;
            this.classString = classString;
        }
Example #3
0
        public List <StudentInfoStruct> GetStudents(string IncludeClass)
        {
            try
            {
                List <StudentInfoStruct> res = new List <StudentInfoStruct>();
                CONN.Open();
                var StringArray_Class = IncludeClass.Split(',');
                if (StringArray_Class.Length == 0)
                {
                    return(null);
                }
                foreach (var ClassString in StringArray_Class)
                {
                    string ClassName;
                    string Major;
                    var    temp = ClassString.Split('.');
                    Major     = temp[0].Trim();
                    ClassName = temp[1].Trim();

                    string           SQL_SELECT_STUDENTS = string.Format(@"SELECT * FROM StudentInfo WHERE [Major] = '{0}' AND [Class] = '{1}'", Major, ClassName);
                    SQLiteCommand    cmd = new SQLiteCommand(SQL_SELECT_STUDENTS, CONN);
                    SQLiteDataReader sdr = cmd.ExecuteReader();
                    while (sdr.Read())
                    {
                        StudentInfoStruct si = new StudentInfoStruct();
                        si.Name            = sdr["Name"].ToString();
                        si.Gender          = sdr["Gender"].ToString();
                        si.Class           = sdr["Class"].ToString();
                        si.Major           = sdr["Major"].ToString();
                        si.PoliticalStatus = sdr["PoliticalStatus"].ToString();
                        si.Nation          = sdr["Nation"].ToString();
                        si.Post            = sdr["Post"].ToString();
                        si.Address         = sdr["Address"].ToString();
                        si.Dorm            = sdr["Dorm"].ToString();
                        si.DormMember      = sdr["DormMember"].ToString();
                        si.Economic        = sdr["Economic"].ToString();
                        si.BonusAndPenalty = sdr["BonusAndPenalty"].ToString();
                        si.Study           = sdr["Study"].ToString();
                        si.Habby           = sdr["Habby"].ToString();
                        si.PhotoPath       = sdr["PhotoPath"].ToString();
                        si.ID     = sdr["ID"].ToString();
                        si.Job    = sdr["Job"].ToString();
                        si.Number = sdr["Number"].ToString();
                        if (!File.Exists(si.PhotoPath))
                        {
                            continue;
                        }
                        res.Add(si);
                    }
                    sdr.Close();
                }
                CONN.Close();
                return(res);
            }
            catch
            {
                return(new List <StudentInfoStruct>());
            }
        }
Example #4
0
 public List <string> GetPorts()
 {
     if (ClassString.Any(x => x.Contains("port")))
     {
         return(ClassString.Where(x => x.Contains("port")).ToList());
     }
     return(null);
 }
Example #5
0
 static public void exit_program(ClassSystem obj, int code, ClassString mesg)
 {
     if (mesg != null)
     {
         Bard.log("EXITING: " + mesg.data);
     }
     PlasmacoreWP7.Main.instance.Exit();
 }
Example #6
0
    int BothTypes(ClassString a, out StructString b)
    {
        a.name = "Betty";
        b.name = "Veronica";


        return(5);
    }
Example #7
0
 public string GetClockSync()
 {
     if (ClassString.Any(x => x.Contains("clock synchronization")))
     {
         var trapString = ClassString.Single(x => x.Contains("clock synchronization"));
         return(trapString.Split(' ').ElementAt(3));
     }
     return("Disable");
 }
Example #8
0
 public int?GetClockPriority()
 {
     if (ClassString.Any(x => x.Contains("clock priority")))
     {
         var trapString = ClassString.Single(x => x.Contains("clock priority"));
         return(Convert.ToInt32(trapString.Split(' ').ElementAt(3)));
     }
     return(null);
 }
Example #9
0
        static public void print(ClassStdOutWriter obj, ClassString st)
        {
            String cst = Bard.cs_str(st);

            if (cst.Length > 1 || cst[0] != 10)
            {
                Bard.log(cst);
            }
        }
Example #10
0
        static public void native_copy(ClassObject builder, ClassString bard_st, char[] array, int to_index)
        {
            String st = bard_st.data;

            for (int i = 0; i < st.Length; ++i)
            {
                array[to_index + i] = st[i];
            }
        }
Example #11
0
 public int?GetCarrier()
 {
     if (ClassString.Any(x => x.Contains("carrier")))
     {
         var trapString = ClassString.Single(x => x.Contains("carrier"));
         return(Convert.ToInt32(trapString.Split(' ').ElementAt(3)));
     }
     return(null);
 }
Example #12
0
        private string GetIp()
        {
            var ipRow = ClassString.FirstOrDefault(x => x.Contains("ip address"));

            if (ipRow is null)
            {
                return("NULL");
            }
            return(ipRow.Split(' ').ElementAt(3));
        }
Example #13
0
        public void ClassStringArray()
        {
            var array = new ClassString[size];

            for (int i = 0; i < size; i++)
            {
                var tmp = new ClassString("0");
                array[i] = tmp;
            }
        }
Example #14
0
        public void ClassStringList()
        {
            var list = new List <ClassString>();

            for (int i = 0; i < size; i++)
            {
                var tmp = new ClassString("0");
                list.Add(tmp);
            }
        }
Example #15
0
        private void ProcessBtn_Click(object sender, EventArgs e)
        {
            string str = InputTextBox.Text;

            ClassString cs = new ClassString(str);

            string answer = cs.CountWordsWithA().ToString();

            OutputTextLabel.Text = answer;
        }
Example #16
0
        // Group: Functions
        // __________________________________________________________________________


        public ImageLink()
        {
            imageLinkID   = 0;
            originalText  = null;
            path          = default(Path);
            fileID        = 0;
            classString   = new ClassString();
            classID       = 0;
            targetFileID  = 0;
            targetScore   = 0;
            ignoredFields = IgnoreFields.None;
        }
Example #17
0
        static public char[] to_Array(ClassString bard_st)
        {
            String st = bard_st.data;

            int count = st.Length;

            char[] result = new char[count];
            for (int i = 0; i < count; ++i)
            {
                result[i] = st[i];
            }
            return(result);
        }
Example #18
0
        /* Function: CommonInit
         * Common initialization done from all the constructors.
         */
        private void CommonInit()
        {
            isRootElement = false;

            maximumEffectiveChildAccessLevel = AccessLevel.Unknown;
            defaultDeclaredChildAccessLevel  = AccessLevel.Unknown;
            defaultChildLanguageID           = 0;
            defaultChildClassString          = new ClassString();
            defaultChildClassStringSet       = false;
            childContextString    = new ContextString();
            childContextStringSet = false;

            endingPosition = new Position(-1, -1);
        }
Example #19
0
 public int?GetTrapRate(string inOut, int index)
 {
     if (ClassString.Any(x => x.Contains("trap") && x.Contains(inOut)))
     {
         var trapString = ClassString.Single(x => x.Contains("trap") && x.Contains(inOut));
         try
         {
             return(Convert.ToInt32(trapString.Split(' ').ElementAt(index)));
         }
         catch
         {
             return(null);
         }
     }
     return(null);
 }
Example #20
0
        static public int opCMP(ClassString st1, ClassString st2)
        {
            if (st1 == st2)
            {
                return(0);
            }
            if (st2 == null)
            {
                return(1);
            }

            int count = st1.data.Length;

            if (count > st2.data.Length)
            {
                count = st2.data.Length;
            }

            String data1 = st1.data;
            String data2 = st2.data;

            for (int i = 0; i < count; ++i)
            {
                if (data1[i] != data2[i])
                {
                    if (data1[i] < data2[i])
                    {
                        return(-1);
                    }
                    else
                    {
                        return(1);
                    }
                }
            }

            // Equal so far
            if (count < st1.data.Length)
            {
                return(1);
            }
            if (count < st2.data.Length)
            {
                return(-1);
            }
            return(0);
        }
Example #21
0
        static public void open_url(ClassSystem obj, ClassString url)
        {
            String url_str = Bard.cs_str(url);

            if (url_str.StartsWith("http"))
            {
                Microsoft.Phone.Tasks.WebBrowserTask task = new Microsoft.Phone.Tasks.WebBrowserTask();
                task.URL = url_str;
                task.Show();
            }
            else
            {
                Microsoft.Phone.Tasks.MarketplaceDetailTask task = new Microsoft.Phone.Tasks.MarketplaceDetailTask();
                task.ContentType       = Microsoft.Phone.Tasks.MarketplaceContentType.Applications;
                task.ContentIdentifier = url_str;
                task.Show();
            }
        }
Example #22
0
        // Group: Functions
        // __________________________________________________________________________


        public Link()
        {
            linkID        = 0;
            type          = LinkType.NaturalDocs;
            textOrSymbol  = null;
            context       = new ContextString();
            contextID     = 0;
            fileID        = 0;
            classString   = new ClassString();
            classID       = 0;
            languageID    = 0;
            endingSymbol  = new EndingSymbol();
            targetTopicID = 0;
            targetClassID = 0;
            targetScore   = 0;

            ignoredFields = IgnoreFields.None;
        }
Example #23
0
    void Start()
    {
        ClassString myClassString = new ClassString();


        StructString myStructString;


        myClassString.name  = "MyClassString";
        myStructString.name = "MyStructString";

        Debug.Log("myClassString.name:" + myClassString.name + " myStructString.name" + myStructString.name);


        BothTypes(myClassString, out myStructString);

        Debug.Log("AFTER myClassString.name:" + myClassString.name + " myStructString.name" + myStructString.name);
    }
Example #24
0
        public void ClassStringArrayPool()
        {
            var arrayPool = ArrayPool <ClassString> .Shared;
            var array     = arrayPool.Rent(size);

            try
            {
                for (int i = 0; i < size; i++)
                {
                    var tmp = new ClassString("0");
                    array[i] = tmp;
                }
            }
            finally
            {
                arrayPool.Return(array);
            }
        }
Example #25
0
        /// <summary>
        /// 获取其他五位老师的学生照片路径
        /// </summary>
        /// <param name="IncludeClass"></param>
        /// <returns></returns>
        public string[] GetOther5StudentsPhotoPath(string IncludeClass)
        {
            try
            {
                string[] res = new string[5];
                string   str_SQLGETSTUDENT;
                str_SQLGETSTUDENT = "SELECT * FROM StudentInfo WHERE ";
                var    StringArray_Class = IncludeClass.Split(',');
                string ClassName;
                string Major;
                bool   first = true;
                foreach (var ClassString in StringArray_Class)
                {
                    if (!first)
                    {
                        str_SQLGETSTUDENT += " AND";
                    }
                    first = false;
                    var temp = ClassString.Split('.');
                    Major     = temp[0].Trim();
                    ClassName = temp[1].Trim();
                    string t = string.Format(" (Class <> '{0}' AND Major <> '{1}')", ClassName, Major);
                    str_SQLGETSTUDENT += t;
                }
                str_SQLGETSTUDENT += " ORDER BY RANDOM() LIMIT 0, 5";

                CONN.Open();
                var cmd = new SQLiteCommand(str_SQLGETSTUDENT, CONN);
                var sdr = cmd.ExecuteReader();
                int i   = 0;
                while (sdr.Read())
                {
                    res[i] = sdr["PhotoPath"].ToString();
                    i++;
                }
                sdr.Close();
                CONN.Close();
                return(res);
            }
            catch
            {
                return(null);
            }
        }
Example #26
0
        static public bool opEQ(ClassString st1, ClassString st2)
        {
            if (st1 == st2)
            {
                return(true);
            }
            if (st2 == null)
            {
                return(false);
            }

            if (st1.property_hash_code != st2.property_hash_code)
            {
                return(false);
            }

            int count = st1.data.Length;

            if (count != st2.data.Length)
            {
                return(false);
            }

            String data1 = st1.data;
            String data2 = st2.data;

            for (int i = 0; i < count; ++i)
            {
                if (data1[i] != data2[i])
                {
                    return(false);
                }
            }

            return(true);
        }
Example #27
0
 public static void web_request( Object context, ClassString url, 
     AspectDataListener listener)
 {
     WebRequest request = WebRequest.Create(url.data);
       request.BeginGetResponse( web_response_handler, new WebRequestInfo(request,listener) );
 }
Example #28
0
        public static void save_gamestate( ClassResourceManager manager, ClassString filename,
            ClassString content)
        {
            #if WINDOWS
              IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForDomain();
            #else
              IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
            #endif

              IsolatedStorageFileStream outfile = null;
              outfile = storage.OpenFile( filename.data, System.IO.FileMode.Create );

              String data = content.data;
              int count = data.Length;
              for (int i=0; i<count; ++i)
              {
            outfile.WriteByte( (byte) data[i] );
              }
              outfile.Close();
        }
Example #29
0
        public static char[] to_Array( ClassString bard_st )
        {
            String st = bard_st.data;

              int count = st.Length;
              char[] result = new char[ count ];
              for (int i=0; i<count; ++i)
              {
            result[i] = st[i];
              }
              return result;
        }
Example #30
0
 public static void init( Object context, ClassString cmd )
 {
 }
Example #31
0
 public static void print( ClassStdOutWriter obj, ClassString st )
 {
     String cst = Bard.cs_str(st);
       if (cst.Length > 1 || cst[0] != 10)
       {
     Bard.log(cst);
       }
 }
Example #32
0
        public static bool opEQ( ClassString st1, ClassString st2 )
        {
            if (st1 == st2)  return true;
              if (st2 == null) return false;

              if (st1.property_hash_code != st2.property_hash_code) return false;

              int count = st1.data.Length;
              if (count != st2.data.Length) return false;

              String data1 = st1.data;
              String data2 = st2.data;

              for (int i=0; i<count; ++i)
              {
            if (data1[i] != data2[i]) return false;
              }

              return true;
        }
Example #33
0
 public static void init( ClassFileWriter writer, ClassString filename, bool append_mode )
 {
     Bard.log( "TODO: Native FileWriter::init()" );
 }
Example #34
0
        public static bool consume( ClassParseReader reader, ClassString st )
        {
            int count = st.data.Length;
              if (count > reader.property_remaining) return false;

              String data1 = st.data;
              char[] data2 = reader.property_data;
              int i1 = count;
              int i2 = reader.property_pos + count;
              while (i1 > 0)
              {
            if (data1[--i1] != data2[--i2]) return false;
              }

              reader.property_pos += count;
              reader.property_column += count;
              reader.property_remaining -= count;
              return true;
        }
Example #35
0
        /// <summary>
        /// 获取教师信息表
        /// </summary>
        /// <returns></returns>
        public List <TeacherInfoStruct> GetTeacherInfoList()
        {
            string TeacherMajor = string.Empty;
            string IncludeClass = string.Empty;
            string TeacherName  = string.Empty;

            try
            {
                List <TeacherInfoStruct> resList = new List <TeacherInfoStruct>();
                CONN.Open();
                string        SQL_GetAllTeacherInfoList = @"SELECT * FROM TeacherInfo";
                SQLiteCommand cmd = new SQLiteCommand(SQL_GetAllTeacherInfoList, CONN);
                var           sdr = cmd.ExecuteReader();
                while (sdr.Read())
                {
                    TeacherInfoStruct TeacherTemp = new TeacherInfoStruct();
                    //读取一个老师的信息
                    TeacherTemp.Name         = sdr["Name"].ToString();
                    TeacherName              = TeacherTemp.Name;
                    TeacherTemp.Major        = sdr["Major"].ToString();
                    TeacherMajor             = TeacherTemp.Major;
                    TeacherTemp.IncludeClass = sdr["IncludeClass"].ToString();
                    IncludeClass             = TeacherTemp.IncludeClass;
                    //if (string.IsNullOrEmpty(TeacherTemp.IncludeClass))
                    //    continue;
                    #region
                    {
                        string Major     = string.Empty;
                        string ClassName = string.Empty;
                        List <StudentInfoStruct> resStudentList = new List <StudentInfoStruct>();
                        var StringArray_Class = TeacherTemp.IncludeClass.Split(',');
                        if (StringArray_Class.Length == 0)
                        {
                            return(null);
                        }
                        foreach (var ClassString in StringArray_Class)
                        {
                            var temp = ClassString.Split('.');
                            Major     = temp[0].Trim();
                            ClassName = temp[1].Trim();
                            string           SQL_SELECT_STUDENTS = string.Format(@"SELECT * FROM StudentInfo WHERE [Major] = '{0}' AND [Class] = '{1}'", Major, ClassName);
                            SQLiteCommand    cmdStudent          = new SQLiteCommand(SQL_SELECT_STUDENTS, CONN);
                            SQLiteDataReader sdrStudent          = cmdStudent.ExecuteReader();//
                            while (sdrStudent.Read())
                            {
                                StudentInfoStruct si = new StudentInfoStruct();
                                si.Name            = sdrStudent["Name"].ToString();
                                si.Gender          = sdrStudent["Gender"].ToString();
                                si.Class           = sdrStudent["Class"].ToString();
                                si.Major           = sdrStudent["Major"].ToString();
                                si.PoliticalStatus = sdrStudent["PoliticalStatus"].ToString();
                                si.Nation          = sdrStudent["Nation"].ToString();
                                si.Post            = sdrStudent["Post"].ToString();
                                si.Address         = sdrStudent["Address"].ToString();
                                si.Dorm            = sdrStudent["Dorm"].ToString();
                                si.DormMember      = sdrStudent["DormMember"].ToString();
                                si.Economic        = sdrStudent["Economic"].ToString();
                                si.BonusAndPenalty = sdrStudent["BonusAndPenalty"].ToString();
                                si.Study           = sdrStudent["Study"].ToString();
                                si.Habby           = sdrStudent["Habby"].ToString();
                                si.PhotoPath       = sdrStudent["PhotoPath"].ToString();
                                si.ID     = sdrStudent["ID"].ToString();
                                si.Job    = sdrStudent["Job"].ToString();
                                si.Number = sdrStudent["Number"].ToString();
                                if (File.Exists(si.PhotoPath) || File.Exists(si.PhotoPath + ".jpg") || File.Exists(si.PhotoPath + ".png") || File.Exists(si.PhotoPath + ".jpg.jpg"))
                                {
                                    resStudentList.Add(si);
                                }
                            }
                            sdrStudent.Close();
                        }
                        TeacherTemp.StudentList = resStudentList;
                        resList.Add(TeacherTemp);
                    }
                    #endregion
                }
                sdr.Close();
                CONN.Close();
                return(resList);
            }
            catch (Exception e)
            {
                //throw e;
                throw new Exception(TeacherMajor + " - " + TeacherName + "\n\n" + IncludeClass + "\n\n信息格式错误");
            }
        }
Example #36
0
 public static void rename( ClassFile file, ClassString new_name )
 {
     Bard.log( "TODO: NativeFile::rename()" );
 }
Example #37
0
 public static void delete_gamestate( ClassResourceManager manager, ClassString filename )
 {
     #if WINDOWS
       IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForDomain();
     #else
       IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
     #endif
       try
       {
     storage.DeleteFile(filename.data);
       }
       catch (Exception err)
       {
       }
 }
Example #38
0
        public static ClassString load_data_file( ClassResourceManager manager, ClassString filename )
        {
            try
              {
            String cs_filename = filename.data;

            int slash_pos = cs_filename.LastIndexOf('/');
            int other_slash_pos = cs_filename.LastIndexOf('\\');
            if (slash_pos == -1
              || (other_slash_pos != -1 && other_slash_pos < slash_pos))
            {
              slash_pos = other_slash_pos;
            }
            if (slash_pos != -1)
            {
              cs_filename = cs_filename.Substring( slash_pos + 1 );
            }
            cs_filename = "data/" + cs_filename;

            if (!cs_filename.StartsWith("data/")) cs_filename = "data/" + cs_filename;
            Stream infile = TitleContainer.OpenStream(cs_filename);

            int count = (int) infile.Length;
            StringBuilder buffer = new StringBuilder(count);

            for (int i=0; i<count; ++i)
            {
              buffer.Append( (char) infile.ReadByte() );
            }

            infile.Close();

            return new ClassString( buffer.ToString() );
              }
              catch (Exception)
              {
            throw new ClassFileNotFoundError(filename);
              }
        }
Example #39
0
        public static void init( ClassBitmap bitmap, ClassString filename )
        {
            String name = filename.data;

              if (name.Equals("internal:font_system_17"))
              {
            init( bitmap, embedded_font_system_17 );
            return;
              }

              int slash_pos = name.LastIndexOf('/');
              int other_slash_pos = name.LastIndexOf('\\');
              if (slash_pos == -1
            || (other_slash_pos != -1 && other_slash_pos < slash_pos))
              {
            slash_pos = other_slash_pos;
              }
              if (slash_pos != -1)
              {
            name = name.Substring( slash_pos + 1 );
              }

              bool success = true;

              if (name.EndsWith(".png") || name.EndsWith(".jpg") || name.EndsWith(".jpeg"))
              {
            success = load( bitmap, "images/"+name );
              }
              else
              {
            if ( !load( bitmap, "images/" + name + ".png" ) )
            {
              if ( !load( bitmap, "images/" + name + ".jpg" ) )
              {
            success = load( bitmap, "images/" + name + ".jpeg" );
              }
            }
              }

              if ( !success )
              {
            throw new ClassFileNotFoundError(filename);
              }
        }
Example #40
0
 public static void log( ClassApplication app, ClassString mesg )
 {
     Bard.log(mesg.data);
 }
Example #41
0
        public static void configure( ContentManager content, GraphicsDevice device, 
            int display_width, int display_height)
        {
            Plasmacore.content = content;
              Plasmacore.device = device;
              DrawBuffer.init(device);

              GameXC.configure();
              GameXC.singleton_ClassGlobal.property_stdout = new ClassTraceWriter(Bard.CallInit.TRUE);

              Plasmacore.display_width = display_width;
              Plasmacore.display_height = display_height;
              event_launch = GameXC.singleton_ClassSignalManager.find_signal_id(Bard.str("launch"));
              event_update = GameXC.singleton_ClassSignalManager.find_signal_id(Bard.str("update"));
              event_draw   = GameXC.singleton_ClassSignalManager.find_signal_id(Bard.str("draw"));
              event_mouse_move =
            GameXC.singleton_ClassSignalManager.find_signal_id(Bard.str("mouse_move"));
              event_mouse_button =
            GameXC.singleton_ClassSignalManager.find_signal_id(Bard.str("mouse_button"));
              event_key =
            GameXC.singleton_ClassSignalManager.find_signal_id(Bard.str("key"));
        }
Example #42
0
 public static void init( ClassFileReader reader, ClassString filename )
 {
     //reader.property_native_data = null;
 }
Example #43
0
        // Group: Functions
        // __________________________________________________________________________


        /* Function: MergeTopics
         * Takes a list of <Topics> that come from the same class but multiple source files and combines them into a
         * single coherent list.  It assumes all topics from a single file will be consecutive, but otherwise the groups of
         * topics can be in any order.
         */
        public static void MergeTopics(List <Topic> topics, Builder builder)
        {
            if (topics.Count == 0)
            {
                return;
            }

                        #if DEBUG
            // Validate that they're all from the same class and that all of a file's topics are consecutive.

            int         classID     = topics[0].ClassID;
            ClassString classString = topics[0].ClassString;

            if (classID == 0)
            {
                throw new Exception("All topics passed to MergeTopics() must have a class ID set.");
            }

            int currentFileID = topics[0].FileID;
            IDObjects.NumberSet previousFileIDs = new IDObjects.NumberSet();

            for (int i = 1; i < topics.Count; i++)
            {
                if (topics[i].ClassID != classID || topics[i].ClassString != classString)
                {
                    throw new Exception("All topics passed to MergeTopics() must have the same class string and ID.");
                }

                if (topics[i].FileID != currentFileID)
                {
                    if (previousFileIDs.Contains(topics[i].FileID))
                    {
                        throw new Exception("MergeTopics() requires all topics that share a file ID be consecutive.");
                    }

                    previousFileIDs.Add(currentFileID);
                    currentFileID = topics[i].FileID;
                }
            }
                        #endif

            // If the first and last topic have the same file ID, that means the entire list does and we can return it as is.
            if (topics[0].FileID == topics[topics.Count - 1].FileID)
            {
                // We do still have to make sure the first topic isn't embedded though so that classes documented in lists will
                // appear correctly.
                if (topics[0].IsEmbedded)
                {
                    topics[0]            = topics[0].Duplicate();
                    topics[0].IsEmbedded = false;
                }

                return;
            }

            var engineInstance = builder.EngineInstance;
            var files          = engineInstance.Files;
            var commentTypes   = engineInstance.CommentTypes;


            // First we have to sort the topic list by file name.  This ensures that the merge occurs consistently no matter
            // what order the files in the list are in or how the file IDs were assigned.

            List <Topic> sortedTopics = new List <Topic>(topics.Count);

            do
            {
                var lowestFile      = files.FromID(topics[0].FileID);
                var lowestFileIndex = 0;
                var lastCheckedID   = lowestFile.ID;

                for (int i = 1; i < topics.Count; i++)
                {
                    if (topics[i].FileID != lastCheckedID)
                    {
                        var file = files.FromID(topics[i].FileID);

                        if (Path.Compare(file.FileName, lowestFile.FileName) < 0)
                        {
                            lowestFile      = file;
                            lowestFileIndex = i;
                        }

                        lastCheckedID = file.ID;
                    }
                }

                int count = 0;
                for (int i = lowestFileIndex; i < topics.Count && topics[i].FileID == lowestFile.ID; i++)
                {
                    count++;
                }

                sortedTopics.AddRange(topics.GetRange(lowestFileIndex, count));
                topics.RemoveRange(lowestFileIndex, count);
            }while (topics.Count > 0);


            // The topics are all in sortedTopics now, and "topics" is empty.  For clarity going forward, let's rename sortedTopics
            // to remainingTopics, since we have to move them back into topics now.

            List <Topic> remainingTopics = sortedTopics;
            sortedTopics = null;              // for safety


            // Find the best topic to serve as the class definition.

            Topic bestDefinition      = remainingTopics[0];
            int   bestDefinitionIndex = 0;

            for (int i = 1; i < remainingTopics.Count; i++)
            {
                Topic topic = remainingTopics[i];

                if (topic.DefinesClass &&
                    builder.EngineInstance.Links.IsBetterClassDefinition(bestDefinition, topic))
                {
                    bestDefinition      = topic;
                    bestDefinitionIndex = i;
                }
            }


            // Copy the best definition in and everything that follows it in the file.  That will serve as the base for merging.

            int bestDefinitionTopicCount = 1;

            for (int i = bestDefinitionIndex + 1; i < remainingTopics.Count && remainingTopics[i].FileID == bestDefinition.FileID; i++)
            {
                bestDefinitionTopicCount++;
            }

            topics.AddRange(remainingTopics.GetRange(bestDefinitionIndex, bestDefinitionTopicCount));
            remainingTopics.RemoveRange(bestDefinitionIndex, bestDefinitionTopicCount);


            // Make sure the first topic isn't embedded so that classes documented in lists still appear correctly.

            if (topics[0].IsEmbedded)
            {
                topics[0]            = topics[0].Duplicate();
                topics[0].IsEmbedded = false;
            }


            // Delete all the other topics that define the class.  We don't need them anymore.

            for (int i = 0; i < remainingTopics.Count; /* don't auto increment */)
            {
                if (remainingTopics[i].DefinesClass)
                {
                    remainingTopics.RemoveAt(i);
                }
                else
                {
                    i++;
                }
            }


            // Merge any duplicate topics into the list.  This is used for things like header vs. source definitions in C++.

            // First we go through the primary topic list to handle removing list topics and merging individual topics into list
            // topics in the remaining topic list.  Everything else will be handled when iterating through the remaining topic list.

            int topicIndex = 0;
            while (topicIndex < topics.Count)
            {
                var topic = topics[topicIndex];

                // Ignore group topics
                if (topic.IsGroup)
                {
                    topicIndex++;
                    continue;
                }

                int embeddedTopicCount = CountEmbeddedTopics(topics, topicIndex);


                // We don't need to worry about enums until we do remaining topics.

                if (topic.IsEnum)
                {
                    topicIndex += 1 + embeddedTopicCount;
                }


                // If it's not an enum and it's a standalone topic see if it will merge with an embedded topic in the remaining topic
                // list.  We don't have to worry about merging with standalone topics until we do the remaining topic list.

                else if (embeddedTopicCount == 0)
                {
                    int duplicateIndex = FindDuplicateTopic(topic, remainingTopics, builder);

                    if (duplicateIndex == -1)
                    {
                        topicIndex++;
                    }
                    else if (remainingTopics[duplicateIndex].IsEmbedded &&
                             engineInstance.Links.IsBetterTopicDefinition(topic, remainingTopics[duplicateIndex]))
                    {
                        topics.RemoveAt(topicIndex);
                    }
                    else
                    {
                        topicIndex++;
                    }
                }


                // If it's not an enum and we're at a list topic, only remove it if EVERY member has a better definition in the other
                // list.  We can't pluck them out individually.  If even one is documented here that isn't documented elsewhere we
                // keep the entire thing in even if that leads to some duplicates.

                else
                {
                    bool allHaveBetterMatches = true;

                    for (int i = 0; i < embeddedTopicCount; i++)
                    {
                        Topic embeddedTopic  = topics[topicIndex + 1 + i];
                        int   duplicateIndex = FindDuplicateTopic(embeddedTopic, remainingTopics, builder);

                        if (duplicateIndex == -1 ||
                            engineInstance.Links.IsBetterTopicDefinition(embeddedTopic, remainingTopics[duplicateIndex]) == false)
                        {
                            allHaveBetterMatches = false;
                            break;
                        }
                    }

                    if (allHaveBetterMatches)
                    {
                        topics.RemoveRange(topicIndex, 1 + embeddedTopicCount);
                    }
                    else
                    {
                        topicIndex += 1 + embeddedTopicCount;
                    }
                }
            }


            // Now do a more comprehensive merge of the remaining topics into the primary topic list.

            int remainingTopicIndex = 0;
            while (remainingTopicIndex < remainingTopics.Count)
            {
                var remainingTopic = remainingTopics[remainingTopicIndex];

                // Ignore group topics
                if (remainingTopic.IsGroup)
                {
                    remainingTopicIndex++;
                    continue;
                }

                int embeddedTopicCount = CountEmbeddedTopics(remainingTopics, remainingTopicIndex);


                // If we're merging enums, the one with the most embedded topics (documented values) wins.  In practice one
                // should be documented and one shouldn't be, so this will be any number versus zero.

                if (remainingTopic.IsEnum)
                {
                    int duplicateIndex = FindDuplicateTopic(remainingTopic, topics, builder);

                    if (duplicateIndex == -1)
                    {
                        remainingTopicIndex += 1 + embeddedTopicCount;
                    }
                    else
                    {
                        int duplicateEmbeddedTopicCount = CountEmbeddedTopics(topics, duplicateIndex);

                        if (embeddedTopicCount > duplicateEmbeddedTopicCount ||
                            (embeddedTopicCount == duplicateEmbeddedTopicCount &&
                             engineInstance.Links.IsBetterTopicDefinition(remainingTopic, topics[duplicateIndex]) == false))
                        {
                            topics.RemoveRange(duplicateIndex, 1 + duplicateEmbeddedTopicCount);
                            topics.InsertRange(duplicateIndex, remainingTopics.GetRange(remainingTopicIndex, 1 + embeddedTopicCount));
                        }

                        remainingTopics.RemoveRange(remainingTopicIndex, 1 + embeddedTopicCount);
                    }
                }


                // If it's not an enum and it's a standalone topic the one with the best score wins.

                else if (embeddedTopicCount == 0)
                {
                    int duplicateIndex = FindDuplicateTopic(remainingTopic, topics, builder);

                    if (duplicateIndex == -1)
                    {
                        remainingTopicIndex++;
                    }
                    else if (engineInstance.Links.IsBetterTopicDefinition(remainingTopic, topics[duplicateIndex]) == false)
                    {
                        if (topics[duplicateIndex].IsEmbedded)
                        {
                            // Just leave them both in
                            remainingTopicIndex++;
                        }
                        else
                        {
                            topics[duplicateIndex] = remainingTopic;
                            remainingTopics.RemoveAt(remainingTopicIndex);
                        }
                    }
                    else
                    {
                        remainingTopics.RemoveAt(remainingTopicIndex);
                    }
                }


                // If it's not an enum and we're at a list topic, only remove it if EVERY member has a better definition in the other
                // list.  We can't pluck them out individually.  If even one is documented here that isn't documented elsewhere we
                // keep the entire thing in even if that leads to some duplicates.

                else
                {
                    bool allHaveBetterMatches = true;

                    for (int i = 0; i < embeddedTopicCount; i++)
                    {
                        Topic embeddedTopic  = remainingTopics[remainingTopicIndex + 1 + i];
                        int   duplicateIndex = FindDuplicateTopic(embeddedTopic, topics, builder);

                        if (duplicateIndex == -1 ||
                            engineInstance.Links.IsBetterTopicDefinition(embeddedTopic, topics[duplicateIndex]) == false)
                        {
                            allHaveBetterMatches = false;
                            break;
                        }
                    }

                    if (allHaveBetterMatches)
                    {
                        remainingTopics.RemoveRange(remainingTopicIndex, 1 + embeddedTopicCount);
                    }
                    else
                    {
                        remainingTopicIndex += 1 + embeddedTopicCount;
                    }
                }
            }


            // Generate groups from the topic lists.

            // Start at 1 to skip the class topic.
            // Don't group by file ID because topics from other files may have been combined into the list.
            var groupedTopics = GetTopicGroups(topics, 1, false);

            var groupedRemainingTopics = GetTopicGroups(remainingTopics);


            // Delete any empty groups.  We do this on the main group list too for consistency.

            for (int i = 0; i < groupedTopics.Groups.Count; /* don't auto increment */)
            {
                if (groupedTopics.Groups[i].IsEmpty)
                {
                    groupedTopics.RemoveGroupAndTopics(i);
                }
                else
                {
                    i++;
                }
            }

            for (int i = 0; i < groupedRemainingTopics.Groups.Count; /* don't auto increment */)
            {
                if (groupedRemainingTopics.Groups[i].IsEmpty)
                {
                    groupedRemainingTopics.RemoveGroupAndTopics(i);
                }
                else
                {
                    i++;
                }
            }


            // Now merge groups.  If any remaining groups match the title of an existing group, move its members to
            // the end of the existing group.

            int remainingGroupIndex = 0;
            while (remainingGroupIndex < groupedRemainingTopics.Groups.Count)
            {
                var  remainingGroup = groupedRemainingTopics.Groups[remainingGroupIndex];
                bool merged         = false;

                if (remainingGroup.Title != null)
                {
                    for (int groupIndex = 0; groupIndex < groupedTopics.Groups.Count; groupIndex++)
                    {
                        if (groupedTopics.Groups[groupIndex].Title == remainingGroup.Title)
                        {
                            groupedRemainingTopics.MergeGroupInto(remainingGroupIndex, groupedTopics, groupIndex);
                            merged = true;
                            break;
                        }
                    }
                }

                if (merged == false)
                {
                    remainingGroupIndex++;
                }
            }


            // Move any groups with titles that didn't match to the other list.  We insert it after the last group
            // of the same dominant type so function groups stay with other function groups, variable groups stay
            // with other variable groups, etc.

            remainingGroupIndex = 0;
            while (remainingGroupIndex < groupedRemainingTopics.Groups.Count)
            {
                var remainingGroup = groupedRemainingTopics.Groups[remainingGroupIndex];

                if (remainingGroup.Title != null)
                {
                    int bestMatchIndex = -1;

                    // Walk the list backwards because we want it to be after the last group of the type, not the first.
                    for (int i = groupedTopics.Groups.Count - 1; i >= 0; i--)
                    {
                        if (groupedTopics.Groups[i].DominantTypeID == remainingGroup.DominantTypeID)
                        {
                            bestMatchIndex = i;
                            break;
                        }
                    }

                    if (bestMatchIndex == -1)
                    {
                        // Just add them to the end if nothing matches.
                        groupedRemainingTopics.MoveGroupTo(remainingGroupIndex, groupedTopics);
                    }
                    else
                    {
                        groupedRemainingTopics.MoveGroupTo(remainingGroupIndex, groupedTopics, bestMatchIndex + 1);
                    }
                }
                else
                {
                    remainingGroupIndex++;
                }
            }


            // Now we're left with topics that are not in groups.  See if the list contains any titled groups at all.

            bool groupsWithTitles = false;

            foreach (var group in groupedTopics.Groups)
            {
                if (group.Title != null)
                {
                    groupsWithTitles = true;
                    break;
                }
            }


            // If there's no titles we can just append the remaining topics as is.

            if (groupsWithTitles == false)
            {
                groupedTopics.Topics.AddRange(groupedRemainingTopics.Topics);
            }


            // If there are titled groups, see if we can add them to the end of existing groups.  However, only do
            // this if TitleMatchesType is set.  It's okay to put random functions into the group "Functions" but
            // not into something more specific.  If there aren't appropriate groups to do this with, create new ones.

            else
            {
                // We don't care about the remaining groups anymore so we can just work directly on the topics.
                remainingTopics        = groupedRemainingTopics.Topics;
                groupedRemainingTopics = null;                  // for safety

                while (remainingTopics.Count > 0)
                {
                    int type = remainingTopics[0].CommentTypeID;
                    int matchingGroupIndex = -1;

                    for (int i = groupedTopics.Groups.Count - 1; i >= 0; i--)
                    {
                        if (groupedTopics.Groups[i].DominantTypeID == type &&
                            groupedTopics.Groups[i].TitleMatchesType)
                        {
                            matchingGroupIndex = i;
                            break;
                        }
                    }

                    // Create a new group if there's no existing one we can use.
                    if (matchingGroupIndex == -1)
                    {
                        Topic generatedTopic = new Topic(builder.EngineInstance.CommentTypes);
                        generatedTopic.TopicID       = 0;
                        generatedTopic.Title         = builder.EngineInstance.CommentTypes.FromID(type).PluralDisplayName;
                        generatedTopic.Symbol        = SymbolString.FromPlainText_NoParameters(generatedTopic.Title);
                        generatedTopic.ClassString   = topics[0].ClassString;
                        generatedTopic.ClassID       = topics[0].ClassID;
                        generatedTopic.CommentTypeID = builder.EngineInstance.CommentTypes.IDFromKeyword("group");
                        generatedTopic.FileID        = topics[0].FileID;
                        generatedTopic.LanguageID    = topics[0].LanguageID;

                        // In case there's nothing that defines the "group" keyword.
                        if (generatedTopic.CommentTypeID != 0)
                        {
                            groupedTopics.Topics.Add(generatedTopic);
                            groupedTopics.CreateGroup(groupedTopics.Topics.Count - 1, 1);
                        }

                        matchingGroupIndex = groupedTopics.Groups.Count - 1;
                    }

                    for (int i = 0; i < remainingTopics.Count; /* don't auto increment */)
                    {
                        var remainingTopic = remainingTopics[i];

                        // Need to check IsEmbedded because enums values will not have the same type as their parent.
                        if (remainingTopic.CommentTypeID == type || remainingTopic.IsEmbedded)
                        {
                            groupedTopics.AppendToGroup(matchingGroupIndex, remainingTopic);
                            remainingTopics.RemoveAt(i);
                        }
                        else
                        {
                            i++;
                        }
                    }
                }
            }
        }
Example #44
0
 public static void write( ClassFileWriter writer, ClassString st )
 {
     Bard.log( "TODO: Native FileWriter" );
 }
Example #45
0
        // Group: Functions
        // __________________________________________________________________________


        /* Function: Merge
         *
         * Takes a list of <Topics> that come from the same class but multiple source files and rearranges them into a
         * single coherent list.  Some topics may be removed or merged with others.  The original topic list will be changed.
         *
         * Each file's topics should appear consecutively in the list and ideally in source order.  The order of the files is not
         * important but should ideally be consistent from one run to the next.
         *
         * It's possible for this function to reduce the number of topics to zero.  For example, if defining classes with a list
         * topic, the list topic itself will be removed.  You should be able to handle this and treat it as if the topic list had
         * no content.
         */
        public static void Merge(ref List <Topic> topics, Engine.Instance engineInstance)
        {
            try
            {
                var files        = engineInstance.Files;
                var commentTypes = engineInstance.CommentTypes;


                // Filter out any list topics that define members of a hierarchy.  If someone documents classes as part of a list,
                // we only want pages for the individual members, not the list topic.

                for (int i = 0; i < topics.Count; /* no auto-increment */)
                {
                    bool remove = false;

                    if (topics[i].IsList)
                    {
                        var commentType = commentTypes.FromID(topics[i].CommentTypeID);

                        if (commentType.InClassHierarchy || commentType.InDatabaseHierarchy)
                        {
                            remove = true;
                        }
                    }

                    if (remove)
                    {
                        topics.RemoveAt(i);
                    }
                    else
                    {
                        i++;
                    }
                }

                if (topics.Count == 0)
                {
                    return;
                }


                // Validate that they're all from the same class and that all of a file's topics are consecutive.

                                #if DEBUG
                int         classID     = topics[0].ClassID;
                ClassString classString = topics[0].ClassString;

                if (classID == 0)
                {
                    throw new Exception("All topics passed to Merge() must have a class ID set.");
                }

                int currentFileID = topics[0].FileID;
                IDObjects.NumberSet previousFileIDs = new IDObjects.NumberSet();

                for (int i = 1; i < topics.Count; i++)
                {
                    if (topics[i].ClassID != classID || topics[i].ClassString != classString)
                    {
                        throw new Exception("All topics passed to Merge() must have the same class string and ID.");
                    }

                    if (topics[i].FileID != currentFileID)
                    {
                        if (previousFileIDs.Contains(topics[i].FileID))
                        {
                            throw new Exception("Merge() requires all topics that share a file ID be consecutive.");
                        }

                        previousFileIDs.Add(currentFileID);
                        currentFileID = topics[i].FileID;
                    }
                }
                                #endif


                // See if there's multiple source files by comparing the first and last topics' file IDs.  If there's only one source file we'll be
                // able to skip some steps.

                bool multipleSourceFiles = (topics[0].FileID != topics[topics.Count - 1].FileID);


                List <Topic> remainingTopics = null;

                if (multipleSourceFiles)
                {
                    // First we have to sort the topic list by file name.  This ensures that the merge occurs consistently no matter
                    // what order the files in the list are in or how the file IDs were assigned.

                    List <Topic> sortedTopics = new List <Topic>(topics.Count);

                    do
                    {
                        var lowestFile      = files.FromID(topics[0].FileID);
                        var lowestFileIndex = 0;
                        var lastCheckedID   = lowestFile.ID;

                        for (int i = 1; i < topics.Count; i++)
                        {
                            if (topics[i].FileID != lastCheckedID)
                            {
                                var file = files.FromID(topics[i].FileID);

                                if (Path.Compare(file.FileName, lowestFile.FileName) < 0)
                                {
                                    lowestFile      = file;
                                    lowestFileIndex = i;
                                }

                                lastCheckedID = file.ID;
                            }
                        }

                        int count = 0;
                        for (int i = lowestFileIndex; i < topics.Count && topics[i].FileID == lowestFile.ID; i++)
                        {
                            count++;
                        }

                        sortedTopics.AddRange(topics.GetRange(lowestFileIndex, count));
                        topics.RemoveRange(lowestFileIndex, count);
                    }while (topics.Count > 0);


                    // The topics are all in sortedTopics now, and "topics" is empty.  For clarity going forward, let's rename sortedTopics
                    // to remainingTopics, since we have to move them back into topics now.

                    remainingTopics = sortedTopics;
                    sortedTopics    = null;                   // for safety


                    // Find the best topic to serve as the class definition.

                    Topic bestDefinition      = remainingTopics[0];
                    int   bestDefinitionIndex = 0;

                    for (int i = 1; i < remainingTopics.Count; i++)
                    {
                        Topic topic = remainingTopics[i];

                        if (topic.DefinesClass && engineInstance.Links.IsBetterClassDefinition(bestDefinition, topic))
                        {
                            bestDefinition      = topic;
                            bestDefinitionIndex = i;
                        }
                    }


                    // Copy the best definition in and everything that follows it in the file.  That will serve as the base for merging.

                    int bestDefinitionTopicCount = 1;

                    for (int i = bestDefinitionIndex + 1; i < remainingTopics.Count && remainingTopics[i].FileID == bestDefinition.FileID; i++)
                    {
                        bestDefinitionTopicCount++;
                    }

                    topics.AddRange(remainingTopics.GetRange(bestDefinitionIndex, bestDefinitionTopicCount));
                    remainingTopics.RemoveRange(bestDefinitionIndex, bestDefinitionTopicCount);
                }                         // if multipleSourceFiles


                // Make sure the first topic isn't embedded so that classes documented in lists still appear correctly.

                if (topics[0].IsEmbedded)
                {
                    topics[0]            = topics[0].Duplicate();
                    topics[0].IsEmbedded = false;
                }


                // Delete all the other topics that define the class.  We don't need them anymore.

                for (int i = 1; i < topics.Count; /* don't auto increment */)
                {
                    if (topics[i].DefinesClass)
                    {
                        topics.RemoveAt(i);
                    }
                    else
                    {
                        i++;
                    }
                }

                if (multipleSourceFiles)
                {
                    for (int i = 0; i < remainingTopics.Count; /* don't auto increment */)
                    {
                        if (remainingTopics[i].DefinesClass)
                        {
                            remainingTopics.RemoveAt(i);
                        }
                        else
                        {
                            i++;
                        }
                    }


                    // Now merge the remaining topics into the main list.

                    // We loop through this process one file at a time in case some topics have to be merged that aren't present in the
                    // base we chose.  For example, File A has FunctionA but not FunctionZ.  File B and File C both have FunctionZ and
                    // they need to be merged with each other.  If we only did one pass comparing all the remaining topics to the base
                    // we wouldn't see that.

                    while (remainingTopics.Count > 0)
                    {
                        int fileID = remainingTopics[0].FileID;


                        // First pick out and merge duplicates.  This is used for things like combining header and source definitions in C++.

                        for (int remainingTopicIndex = 0;
                             remainingTopicIndex < remainingTopics.Count && remainingTopics[remainingTopicIndex].FileID == fileID;
                             /* no auto-increment */)
                        {
                            var remainingTopic = remainingTopics[remainingTopicIndex];

                            // We're ignoring group topics for now.  They stay in remainingTopics.
                            if (remainingTopic.IsGroup)
                            {
                                remainingTopicIndex++;
                                continue;
                            }

                            int embeddedTopicCount = CountEmbeddedTopics(remainingTopics, remainingTopicIndex);


                            // If we're merging enums, the one with the most embedded topics (documented values) wins.  In practice one
                            // should be documented and one shouldn't be, so this should usually be any number versus zero.

                            if (remainingTopic.IsEnum)
                            {
                                int duplicateIndex = FindDuplicateTopic(remainingTopic, topics, engineInstance);

                                if (duplicateIndex == -1)
                                {
                                    remainingTopicIndex += 1 + embeddedTopicCount;
                                }
                                else
                                {
                                    int duplicateEmbeddedTopicCount = CountEmbeddedTopics(topics, duplicateIndex);

                                    if (embeddedTopicCount > duplicateEmbeddedTopicCount ||
                                        (embeddedTopicCount == duplicateEmbeddedTopicCount &&
                                         engineInstance.Links.IsBetterTopicDefinition(remainingTopic, topics[duplicateIndex]) == false))
                                    {
                                        topics.RemoveRange(duplicateIndex, 1 + duplicateEmbeddedTopicCount);
                                        topics.InsertRange(duplicateIndex, remainingTopics.GetRange(remainingTopicIndex, 1 + embeddedTopicCount));
                                    }

                                    remainingTopics.RemoveRange(remainingTopicIndex, 1 + embeddedTopicCount);
                                }
                            }


                            // If it's not an enum and it's a standalone topic, the one with the best score wins.

                            else if (embeddedTopicCount == 0)
                            {
                                int duplicateIndex = FindDuplicateTopic(remainingTopic, topics, engineInstance);

                                if (duplicateIndex == -1)
                                {
                                    remainingTopicIndex++;
                                }
                                else if (engineInstance.Links.IsBetterTopicDefinition(remainingTopic, topics[duplicateIndex]) == false)
                                {
                                    if (topics[duplicateIndex].IsEmbedded)
                                    {
                                        // Just leave them both in
                                        remainingTopicIndex++;
                                    }
                                    else
                                    {
                                        topics[duplicateIndex] = remainingTopic;
                                        remainingTopics.RemoveAt(remainingTopicIndex);
                                    }
                                }
                                else
                                {
                                    remainingTopics.RemoveAt(remainingTopicIndex);
                                }
                            }


                            // If it's not an enum and we're at a list topic, leave it for now.  We only want to remove it if EVERY member has
                            // a better definition, and those definitions can be in different files, so wait until the list is fully combined.

                            else
                            {
                                remainingTopicIndex += 1 + embeddedTopicCount;
                            }
                        }


                        // Generate groups from the topic lists.

                        // Start at 1 to skip the class topic.
                        var topicGroups = GetTopicGroups(topics, startingIndex: 1);

                        var remainingTopicGroups = GetTopicGroups(remainingTopics, limitToFileID: fileID);


                        // Now merge groups.

                        int remainingGroupIndex = 0;
                        while (remainingGroupIndex < remainingTopicGroups.Groups.Count)
                        {
                            var  remainingGroup = remainingTopicGroups.Groups[remainingGroupIndex];
                            bool merged         = false;

                            // If the group is empty because all its members were merged as duplicates, just delete it.
                            if (remainingGroup.IsEmpty)
                            {
                                remainingTopicGroups.RemoveGroupAndTopics(remainingGroupIndex);
                                merged = true;
                            }

                            // If it matches the title of an existing group, move its members to the end of the existing group.
                            else if (remainingGroup.Title != null)
                            {
                                for (int groupIndex = 0; groupIndex < topicGroups.Groups.Count; groupIndex++)
                                {
                                    if (topicGroups.Groups[groupIndex].Title == remainingGroup.Title)
                                    {
                                        remainingTopicGroups.MergeGroupInto(remainingGroupIndex, topicGroups, groupIndex);
                                        merged = true;
                                        break;
                                    }
                                }

                                // If the group had a title but didn't match one on the other list, insert it after the last group of the same
                                // dominant type so function groups stay with other function groups, variable groups stay with other variable
                                // groups, etc.
                                if (merged == false)
                                {
                                    int bestMatchIndex = -1;

                                    // Walk the list backwards because we want it to be after the last group of the type, not the first.
                                    for (int i = topicGroups.Groups.Count - 1; i >= 0; i--)
                                    {
                                        if (topicGroups.Groups[i].DominantTypeID == remainingGroup.DominantTypeID)
                                        {
                                            bestMatchIndex = i;
                                            break;
                                        }
                                    }

                                    if (bestMatchIndex == -1)
                                    {
                                        // Just add the group to the end if nothing matches.
                                        remainingTopicGroups.MoveGroupTo(remainingGroupIndex, topicGroups);
                                    }
                                    else
                                    {
                                        remainingTopicGroups.MoveGroupTo(remainingGroupIndex, topicGroups, bestMatchIndex + 1);
                                    }

                                    merged = true;
                                }
                            }

                            if (!merged)
                            {
                                remainingGroupIndex++;
                            }
                        }


                        // Now we're left with topics that are not in titled groups, meaning the file itself had no group topics or there were
                        // topics that appeared before the first one.  See if the base contains any titled groups.

                        bool hasGroupsWithTitles = false;

                        foreach (var group in topicGroups.Groups)
                        {
                            if (group.Title != null)
                            {
                                hasGroupsWithTitles = true;
                                break;
                            }
                        }


                        // If there's no titles we can just append the remaining topics as is.

                        if (hasGroupsWithTitles == false)
                        {
                            int fileIDLimit = 0;

                            while (fileIDLimit < remainingTopics.Count && remainingTopics[fileIDLimit].FileID == fileID)
                            {
                                fileIDLimit++;
                            }

                            if (fileIDLimit > 0)
                            {
                                topics.AddRange(remainingTopics.GetRange(0, fileIDLimit));
                                remainingTopics.RemoveRange(0, fileIDLimit);
                            }
                        }


                        // If there are titled groups, see if we can add them to the end of existing groups.  However, only do
                        // this if TitleMatchesType is set.  It's okay to put random functions into the group "Functions" but
                        // not into something more specific.  If there aren't appropriate groups to do this with, create new ones.

                        else
                        {
                            while (remainingTopics.Count > 0 && remainingTopics[0].FileID == fileID)
                            {
                                int type = remainingTopics[0].CommentTypeID;
                                int matchingGroupIndex = -1;

                                for (int i = topicGroups.Groups.Count - 1; i >= 0; i--)
                                {
                                    if (topicGroups.Groups[i].DominantTypeID == type &&
                                        topicGroups.Groups[i].TitleMatchesType)
                                    {
                                        matchingGroupIndex = i;
                                        break;
                                    }
                                }

                                // Create a new group if there's no existing one we can use.
                                if (matchingGroupIndex == -1)
                                {
                                    Topic generatedTopic = new Topic(engineInstance.CommentTypes);
                                    generatedTopic.TopicID       = 0;
                                    generatedTopic.Title         = engineInstance.CommentTypes.FromID(type).PluralDisplayName;
                                    generatedTopic.Symbol        = SymbolString.FromPlainText_NoParameters(generatedTopic.Title);
                                    generatedTopic.ClassString   = topics[0].ClassString;
                                    generatedTopic.ClassID       = topics[0].ClassID;
                                    generatedTopic.CommentTypeID = engineInstance.CommentTypes.IDFromKeyword("group", topics[0].LanguageID);
                                    generatedTopic.FileID        = topics[0].FileID;
                                    generatedTopic.LanguageID    = topics[0].LanguageID;

                                    // In case there's nothing that defines the "group" keyword.
                                    if (generatedTopic.CommentTypeID != 0)
                                    {
                                        topicGroups.Topics.Add(generatedTopic);
                                        topicGroups.CreateGroup(topicGroups.Topics.Count - 1, 1);
                                    }

                                    matchingGroupIndex = topicGroups.Groups.Count - 1;
                                }

                                do
                                {
                                    int topicsToMove = 1 + CountEmbeddedTopics(remainingTopics, 0);

                                    while (topicsToMove > 0)
                                    {
                                        topicGroups.AppendToGroup(matchingGroupIndex, remainingTopics[0]);
                                        remainingTopics.RemoveAt(0);
                                        topicsToMove--;
                                    }
                                }while (remainingTopics.Count > 0 && remainingTopics[0].CommentTypeID == type);
                            }
                        }
                    }


                    // Now that everything's merged into one list, make another pass to merge list topics.

                    for (int topicIndex = 0; topicIndex < topics.Count; /* no auto-increment */)
                    {
                        var topic = topics[topicIndex];

                        // Ignore group topics
                        if (topic.IsGroup)
                        {
                            topicIndex++;
                            continue;
                        }

                        int embeddedTopicCount = CountEmbeddedTopics(topics, topicIndex);

                        // Ignore single topics and enums.  Enums have embedded topics but we already handled them earlier.
                        if (embeddedTopicCount == 0 || topic.IsEnum)
                        {
                            topicIndex += 1 + embeddedTopicCount;
                            continue;
                        }


                        // If we're here we're at a list topic.  Compare its members with every other member in the list.  Remove standalone
                        // topics if the list contains a better definition, but only remove the list if EVERY member has a better definition
                        // somewhere else.  If only some do we'll leave in the whole thing and have duplicates instead of trying to pluck out
                        // individual embedded topics.

                        bool embeddedContainsBetterDefinitions = false;
                        bool embeddedContainsNonDuplicates     = false;

                        for (int embeddedTopicIndex = topicIndex + 1;
                             embeddedTopicIndex < topicIndex + 1 + embeddedTopicCount;
                             embeddedTopicIndex++)
                        {
                            var embeddedTopic         = topics[embeddedTopicIndex];
                            var embeddedTopicLanguage = engineInstance.Languages.FromID(embeddedTopic.LanguageID);
                            var foundDuplicate        = false;

                            for (int potentialDuplicateTopicIndex = 0; potentialDuplicateTopicIndex < topics.Count; /* no auto-increment */)
                            {
                                /* Skip ones in the list topic */
                                if (potentialDuplicateTopicIndex == topicIndex)
                                {
                                    potentialDuplicateTopicIndex += 1 + embeddedTopicCount;
                                    continue;
                                }

                                var potentialDuplicateTopic = topics[potentialDuplicateTopicIndex];

                                if (embeddedTopicLanguage.Parser.IsSameCodeElement(embeddedTopic, potentialDuplicateTopic))
                                {
                                    foundDuplicate = true;

                                    // If the current embedded topic is the better definition
                                    if (engineInstance.Links.IsBetterTopicDefinition(potentialDuplicateTopic, embeddedTopic))
                                    {
                                        embeddedContainsBetterDefinitions = true;

                                        // If the duplicate is also embedded, leave it alone.  Either the duplicate is going to be allowed to exist
                                        // because neither list can be completely removed, or it will be removed later when its own list is checked
                                        // for duplicates.
                                        if (potentialDuplicateTopic.IsEmbedded)
                                        {
                                            potentialDuplicateTopicIndex++;
                                        }

                                        // If the duplicate is not embedded we can remove it.
                                        else
                                        {
                                            topics.RemoveAt(potentialDuplicateTopicIndex);

                                            if (potentialDuplicateTopicIndex < topicIndex)
                                            {
                                                topicIndex--;
                                                embeddedTopicIndex--;
                                            }
                                        }
                                    }

                                    // If the potential duplicate is the better definition.  We don't need to do anything here because we're just
                                    // looking to see if all of them have better definitions elsewhere, which can be determined by whether this
                                    // group contains any better definitions or non-duplicates.
                                    else
                                    {
                                        potentialDuplicateTopicIndex++;
                                    }
                                }

                                // Not the same code element
                                else
                                {
                                    potentialDuplicateTopicIndex++;
                                }
                            }

                            if (!foundDuplicate)
                            {
                                embeddedContainsNonDuplicates = true;
                            }
                        }


                        // Now that we've checked every embedded topic against every other topic, remove the entire list only if EVERY
                        // member has a better definition somewhere else, which is the same as saying it doesn't contain any better
                        // topic definitions or non-duplicates.

                        if (embeddedContainsBetterDefinitions == false && embeddedContainsNonDuplicates == false)
                        {
                            topics.RemoveRange(topicIndex, 1 + embeddedTopicCount);
                        }
                        else
                        {
                            topicIndex += 1 + embeddedTopicCount;
                        }
                    }
                }                          // if multipleSourceFiles


                // Now that everything's merged, delete any empty groups.  We do this on the main group list for consistency,
                // since we were doing it on the remaining group list during merging.  Also, there may be new empty groups after
                // merging the list topics.

                // Start at 1 to skip the class topic.
                var groupedTopics = GetTopicGroups(topics, startingIndex: 1);

                for (int i = 0; i < groupedTopics.Groups.Count; /* don't auto increment */)
                {
                    if (groupedTopics.Groups[i].IsEmpty)
                    {
                        groupedTopics.RemoveGroupAndTopics(i);
                    }
                    else
                    {
                        i++;
                    }
                }
            }

            catch (Exception e)
            {
                // Build a message to show the class we crashed on
                if (topics != null && topics.Count >= 1 && topics[0].ClassString != null)
                {
                    var           topic = topics[0];
                    StringBuilder task  = new StringBuilder("Building class view for");

                    // Hierarchy
                    if (topic.ClassString.Hierarchy == Hierarchy.Database)
                    {
                        task.Append(" database");
                    }
                    else
                    {
                        // Language name
                        var language = (topics[0].LanguageID > 0 ? engineInstance.Languages.FromID(topics[0].LanguageID) : null);

                        if (language == null)
                        {
                            task.Append(" language ID " + topics[0].LanguageID + " class");
                        }
                        else
                        {
                            task.Append(" " + language.Name + " class");
                        }
                    }

                    // Class name
                    task.Append(" " + topic.ClassString.Symbol.FormatWithSeparator('.'));

                    e.AddNaturalDocsTask(task.ToString());
                }

                throw;
            }
        }
Example #46
0
 public static void init( ClassObject socket, ClassString address, int port )
 {
     Bard.log( "TODO: NativeSocket::init()" );
 }
Example #47
0
 public static void exit_program( ClassSystem obj, int code, ClassString mesg )
 {
     if (mesg != null) Bard.log( "EXITING: " + mesg.data );
       PlasmacoreWP7.Main.instance.Exit();
 }
Example #48
0
        public static int opCMP( ClassString st1, ClassString st2 )
        {
            if (st1 == st2)  return 0;
              if (st2 == null) return 1;

              int count = st1.data.Length;
              if (count > st2.data.Length) count = st2.data.Length;

              String data1 = st1.data;
              String data2 = st2.data;

              for (int i=0; i<count; ++i)
              {
            if (data1[i] != data2[i])
            {
              if (data1[i] < data2[i]) return -1;
              else                     return  1;
            }
              }

              // Equal so far
              if (count < st1.data.Length) return  1;
              if (count < st2.data.Length) return -1;
              return 0;
        }
Example #49
0
 public static void open_url( ClassSystem obj, ClassString url )
 {
     String url_str = Bard.cs_str(url);
       if (url_str.StartsWith("http"))
       {
     Microsoft.Phone.Tasks.WebBrowserTask task = new Microsoft.Phone.Tasks.WebBrowserTask();
     task.URL = url_str;
     task.Show();
       }
       else
       {
     Microsoft.Phone.Tasks.MarketplaceDetailTask task = new Microsoft.Phone.Tasks.MarketplaceDetailTask();
     task.ContentType = Microsoft.Phone.Tasks.MarketplaceContentType.Applications;
     task.ContentIdentifier = url_str;
     task.Show();
       }
 }
Example #50
0
 public static ClassString substring( ClassString st, int i1, int i2 )
 {
     return new ClassString( st.data.Substring( i1, (i2-i1)+1 ) );
 }
Example #51
0
 public static String cs_str( ClassString st )
 {
     return st.data;
 }
Example #52
0
 public static void native_copy( ClassObject builder, ClassString bard_st, char[] array, int to_index )
 {
     String st = bard_st.data;
       for (int i=0; i<st.Length; ++i)
       {
     array[to_index+i] = st[i];
       }
 }
Example #53
0
        public static void init( ClassNativeSound sound, ClassString filename )
        {
            String fname = filename.data;
              if (fname.EndsWith(".wav") || fname.EndsWith(".mp3") || fname.EndsWith(".m4a"))
              {
            fname = fname.Substring( 0, fname.Length - 4);
              }

              WP7Sound sound_data = null;
              try
              {
            sound_data = new WP7SoundEffect(
              Plasmacore.content.Load<SoundEffect>(fname) );
              }
              catch (Exception)
              {
            try
            {
              sound_data = new WP7Song( Plasmacore.content.Load<Song>(fname) );
            }
            catch (Exception)
            {
              Bard.log( "Sound not found: " + filename.data );
              return;
            }
              }
              sound.property_native_data = sound_data;
        }
Example #54
0
 public ClassException( ClassString local_0_message)
 {
     init_object();
       init(local_0_message);
 }
Example #55
0
 public static void prompt( ClassObject context, ClassString title, ClassString description,
     ClassString default_value)
 {
     NativeWindowsPhone7.default_value = default_value.data;
       Guide.BeginShowKeyboardInput( PlayerIndex.One, title.data, description.data,
     (default_value.data == null) ? "" : default_value.data, on_keyboard_finished, null );
 }
Example #56
0
 public string GetDcn() => ClassString.Contains("undo dcn") ? "Disable" : "Enable";
Example #57
0
 public virtual void init()
 {
     property_message = new ClassString("");
 }
Example #58
0
 public virtual void init(ClassString local_0_message)
 {
     property_message = local_0_message;
 }
Example #59
0
        public static ClassString load_gamestate( ClassResourceManager manager, ClassString filename )
        {
            #if WINDOWS
              IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForDomain();
            #else
              IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
            #endif
              try
              {
            IsolatedStorageFileStream infile;
            infile = storage.OpenFile(filename.data, System.IO.FileMode.Open);

            int count = (int)infile.Length;
            StringBuilder buffer = new StringBuilder(count);

            for (int i = 0; i < count; ++i)
            {
              buffer.Append( (char)infile.ReadByte() );
            }

            infile.Close();

            return new ClassString( buffer.ToString() );
              }
              catch (Exception)
              {
            throw new ClassFileNotFoundError(filename);
              }
        }