serbanov Ответов: 2

C# рекурсивно разбирает некоторые файлы и печатает некоторую информацию


Привет сообщество CodeProject,

Я работаю над инструментом, который анализирует некоторые файлы для поиска других файлов ... Чтобы быть более конкретным, проанализируйте файл. c, чтобы найти файлы. h, а затем для каждого из файлов .h проанализируйте их и извлеките их зависимости, пока они не попадут в пустой заголовок.

Вопрос: как выглядит структура, которую я пытаюсь разобрать и получить нужную информацию ?

Один:

Видеть здесь

Вопрос: что у вас есть до сих пор ?

Ответ: Ну, у меня есть несколько функций, которые отлично справляются с получением файла .C и первого раунда файлов .h, содержащихся в файлах .C. Моя проблема заключается в том, что когда я хочу напечатать их в файле Excel, я хочу напечатать их в таких группах, как

File.C-->Header.H --> Header1.H - > all dependecies of Header1.H like the above example
                    -->2ndHeader.H --> Header2.H ->all dependecies of Header2.H like the above example
                                   --> Header3.H ->all dependecies of Header3.H like the above example


В: Да, но что у вас есть до сих пор в качестве выхода ?
Ответ: у меня есть следующая схема вывода, я опубликую код в разделе "Что вы пробовали?" раздел.


В качестве вывода на данный момент у меня есть следующий файл .txt :

File Header1.h depends of following files : 
----> Header2.h with the following path: 
				 -----> Their location
----> Header3.h with the following path: 
				 -----> Their location
----> Header4.h with the following path: 
				 -----> Their location
----> Completed dependencies of Header1.h


File Header2.h depends of following files : 

 ----> Header5.h with the following path: 
				 -----> Their location
----> Header6.h with the following path: 
				 -----> Their location
----> Completed dependencies of Header2.h



File Header3.h depends of following files : 
----> Header2.h with the following path: 
				 -----> Their location
----> Header4.h with the following path: 
				 -----> Their location
----> Completed dependencies of Header3.h



File Header4.h depends of following files : 
----> Header7.h with the following path: 
				 -----> Their location
----> Header8.h with the following path: 
				 -----> Their location
----> Header9.h with the following path: 
				 -----> Their location
----> Header10.h with the following path: 
				 -----> Their location
----> Header11.h with the following path: 
				 -----> Their location
----> Completed dependencies of Header4.h



File Header5.h depends of following files : 
----> Completed dependencies of Header5.h



File Header6.h depends of following files : 
----> Header12.h with the following path: 
				 -----> Their location
----> Completed dependencies of Header6.h



File Header7.h depends of following files : 
----> Completed dependencies of Header7.h



File Header8.h depends of following files : 
----> Completed dependencies of Header8.h



File Header9.h depends of following files : 
----> Completed dependencies of Header9.h



File Header10.h depends of following files : 
----> Completed dependencies of Header10.h



File Header11.h depends of following files : 
----> Completed dependencies of Header11.h



File Header12.h depends of following files : 
----> Header13.h with the following path: 
				 -----> Their location
----> Completed dependencies of Header12.h



File Header13.h depends of following files : 
----> Completed dependencies of Header13.h



Вопрос: Какой выход вы хотите ?
Ответ: следующий .txt:

File Header1.h depends of following files : 
----> Header2.h with the following path: 
				 -----> Their location
				 
				File Header2.h depends of following files : 

				----> Header5.h with the following path: 
				-----> Their location
				 
						File Header5.h depends of following files : 
						----> Completed dependencies of Header5.h
					
				----> Header6.h with the following path: 
				-----> Their location
				 
						File Header6.h depends of following files : 
				
						----> Header12.h with the following path: 
						-----> Their location
						----> Completed dependencies of Header6.h
						
							File Header12.h depends of following files : 
							
							----> Header13.h with the following path: 
							-----> Their location
							----> Completed dependencies of Header12.h

								File Header13.h depends of following files : 
								----> Completed dependencies of Header13.h
								
								
				 
				----> Completed dependencies of Header2.h
					
					
----> Header3.h with the following path: 
				 -----> Their location
				 
					File Header3.h depends of following files : 
					
					----> Header2.h with the following path: 
					-----> Their location
					
					----> Header4.h with the following path: 
					-----> Their location
					
				----> Completed dependencies of Header3.h

----> Header4.h with the following path: 
				 -----> Their location
				 
				File Header4.h depends of following files : 
				 
				----> Header7.h with the following path: 
				-----> Their location
				
					File Header7.h depends of following files : 
					----> Completed dependencies of Header7.h

				----> Header8.h with the following path: 
				-----> Their location
				
					File Header8.h depends of following files : 
					----> Completed dependencies of Header8.h

				----> Header9.h with the following path: 
				-----> Their location
				
					File Header9.h depends of following files : 
					----> Completed dependencies of Header9.h

				----> Header10.h with the following path: 
				-----> Their location
					
					File Header10.h depends of following files : 
					----> Completed dependencies of Header10.h

				----> Header11.h with the following path: 
				-----> Their location
				
					File Header11.h depends of following files : 
					----> Completed dependencies of Header11.h
				
				----> Completed dependencies of Header4.h
				 
----> Completed dependencies of Header1.h


Что мне нужно изменить в своем коде, чтобы получить второй вывод ?

Что я уже пробовал:

public static void _searchHofHeaders(FileInfo fisierH, string path, List<FileInfo> _listOfChead)
{
    List<FileInfo> _tempListOfCheaders = _listOfChead;
    if (fisierH != null)
    {
        StreamReader _file;
        _file = new StreamReader(fisierH.FullName);
        string line = null;
        try
        {
            if (_HeaderFilesToIgnore.Contains(fisierH.Name) != true)
            {
                _HeaderFilesToIgnore.Add(fisierH.Name);

                while ((line = _file.ReadLine()) != null)
                {
                    String sourcestring = line;
                    int flag = -1;

                    if ((line.StartsWith("/*") == true && line.EndsWith("*/") != true) || line.StartsWith("//") == true
                    || (line.StartsWith("/*") == true && line.EndsWith("*/") == true) || line.Contains("#include") != true)
                    {
                        flag = 1;

                    }
                    else
                    {

                        string[] _LineContent;

                        if (line.StartsWith("#include") != true)
                        {
                            if ((line.Contains("#include") == true && line.Contains("/*") == true && line.Contains("*/") == true && line.Contains("//") == true) ||
                            (line.Contains("#include") == true && line.Contains("//") == true) || (line.Contains("#include") == true && line.Contains("/*") == true && line.Contains("*/") == true)
                            || (line.Contains("#include") == true && line.Contains("/*") != true && line.Contains("*/") == true))
                            {
                                _LineContent = line.Split(new string[] { "#include" }, StringSplitOptions.RemoveEmptyEntries);

                                for (int _i = 0; _i < _LineContent.Length; _i++)
                                {
                                    if (_i == 0)
                                    {
                                        if ((_LineContent[_i].Contains("/*") == true && _LineContent[_i].Contains("*/") != true && _LineContent[_i].Contains(".h") == true) || (_LineContent[_i].Contains("//") == true && _LineContent[_i].Contains(".h") == true)
                                        || (_LineContent[_i].Contains("/*") == true && _LineContent[_i].Contains("*/") != true) || (_LineContent[_i].Contains("//") == true && _LineContent.Contains(".h") != true))
                                        flag = 1;
                                    }

                                else
                                    if (_i != 0)
                                    {
                                        if ((_LineContent[_i].Contains("/*") == true && _LineContent[_i].Contains("*/") != true && _LineContent[_i].Contains(".h") == true) || (_LineContent[_i].Contains("//") == true && _LineContent[_i].Contains(".h") == true)
                                        || (_LineContent[_i].Contains("/*") == true && _LineContent[_i].Contains("*/") != true) || (_LineContent[_i].Contains("//") == true && _LineContent.Contains(".h") != true))
                                            flag = 1;
                                    }

                                }
                            }
                        }
                    }

                    if ((line.StartsWith("*/") == true))
                    {
                        flag = 2;
                    }

                    if(flag!=1)
                        {



                                    Regex re = new Regex(@"[A-Za-z0-9\-_]+.h", RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline);
                                    MatchCollection mc = re.Matches(sourcestring);
                                    int mIdx = 0;

                                    foreach (Match m in mc)
                                    {
                                        for (int gIdx = 0; gIdx < m.Groups.Count; gIdx++)
                                        {
                                            int flag_h = 0;
                                            int flag_h1 = 0;
                                            string nume_fisier = m.Groups[gIdx].Value;

                                            if (_headers_to_search.Count != 0)
                                            {
                                                foreach (FileInfo _hToS in _headers_to_search.ToList())
                                                {
                                                    if (nume_fisier.Equals(_hToS.Name) == true)
                                                    {
                                                        flag_h = 1;
                                                    }
                                                }
                                                foreach (FileInfo _hToSfromH in _listOfChead.ToList())
                                                {
                                                    if (nume_fisier.Equals(_hToSfromH.Name) == true)
                                                    {
                                                        flag_h1 = 1;
                                                    }
                                                }

                                                if (flag_h == 1)
                                                {
                                                    foreach (FileInfo _hToS2 in _headers_to_search.ToList())
                                                    {
                                                        if (nume_fisier.Equals(_hToS2.Name) == true)
                                                        {
                                                            _headers_list.Add(_hToS2);
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    if (flag_h1 == 1 && flag_h != 1)
                                                    {
                                                        foreach (FileInfo _hToSfromH1 in _listOfChead.ToList())
                                                        {
                                                            if (nume_fisier.Equals(_hToSfromH1.Name) == true)
                                                            {
                                                                _headers_list.Add(_hToSfromH1);
                                                            }
                                                        }
                                                    }

                                                    else
                                                        if (flag_h1 != 1 && flag_h != 1)
                                                        {
                                                            string _temppath_of_H = _searchFunction(nume_fisier, path);

                                                            if (_temppath_of_H != null)
                                                            {
                                                                FileInfo fisier_h = new FileInfo(_temppath_of_H);
                                                                if (fisier_h != null)
                                                                {
                                                                    _headers_list.Add(fisier_h);
                                                                    _headers_to_search.Add(fisier_h);
                                                                }
                                                            }
                                                        }
                                                }

                                            }
                                            else
                                                if (_headers_to_search.Count == 0)
                                                {

                                                    string _temppath_of_H = _searchFunction(nume_fisier, path);

                                                    if (_temppath_of_H != null)
                                                    {
                                                        FileInfo _fisier_h = new FileInfo(_temppath_of_H);
                                                        if (_fisier_h != null)
                                                        {
                                                            _headers_list.Add(_fisier_h);
                                                            _headers_to_search.Add(_fisier_h);
                                                        }
                                                    }
                                                }
                                        }
                                    }
                                mIdx++;

                        }
                }
            }
        }

        catch (Exception ex)
        { }

        //List<FileInfo> _headers_To_Search = _headers_list.DistinctBy(x => x.Name).ToList();

        _headers_to_search = _headers_to_search.DistinctBy(x => x.Name).ToList();
        _headers_list = _headers_list.DistinctBy(x => x.Name).ToList();

        if (_hFiles_Headers.ContainsKey(fisierH.Name) != true)
        {
            _hFiles_Headers.Add(fisierH.Name, _headers_list);
        }
        _headers_list = new List<FileInfo>();
        _file.Close();

        _HeaderFilesToIgnore = _HeaderFilesToIgnore.Distinct().ToList();


       foreach (FileInfo fisH in _headers_to_search.ToList())
       {
            try
            {
                if (_HeaderFilesToIgnore.Contains(fisH.Name) != true)
                {

                    _searchHofHeaders(fisH, path,_tempListOfCheaders);
                }
            }
            catch (Exception ex)
            {
                break;
            }

        }



    }
}



Этот код предназначен только для этой части программы. Функция поиска имеет отношение к тому, что я должен делать.

[no name]

Я понятия не имею, в чем заключается ваш настоящий вопрос, но я уверен, что вы скоро придете, чтобы ответить себе, как это, кажется, входит в вашу привычку.

serbanov

Ну, на самом деле нет, но если я найду решение своей проблемы, я опубликую его :) так что некоторые другие люди будут знать, если они столкнутся с чем-то, как я. :) Вопрос прост: как получить 2-й выход ? Я помещаю свои данные в словарь, но так, как я это делаю, это не то, что мне нужно ... Я ставлю эти вопросы и ответы, чтобы избежать нескольких вопросов.

#realJSOP

FWIW, я не могу перейти по ссылке, которую вы предоставили (запрещена нашей конфигурацией коммутатора). ИМХО, ваш "желаемый результат" слишком длинный и просто загромождает ваш вопрос. Более простой формат будет иметь большое значение для получения ответа на ваш вопрос.

Наконец, не похоже, что вы действительно что-то пробовали. Вы просто разместили код, который "не применяется", но нет кода, показывающего вашу попытку желаемого рекурсивного решения.

serbanov

ИДК почему вам кажется что я не пробовал рекурсивное решение так как в моем коде у меня есть :


foreach (FileInfo fisH in _headers_to_search.Список())
{
пробовать
{
если (_HeaderFilesToIgnore.Содержит(fisH.Name) != правда)
{

_searchHofHeaders(рыба, путь, _tempListOfCheaders);
}
}
поймать (исключение бывший)
{
перерыв;
}

}

Дело вот в чем ... я опубликовал изображение того, как я хочу, чтобы моя программа разбиралась ... и получите мою информацию !

2 Ответов

Рейтинг:
2

#realJSOP

Попробуйте сделать это в Visual Studio

Настройки-и gt; Свойства -> конфигурация; с/С++ - и GT; дополнительно -&ГТ; шоу включает в себя

Я думаю,что это создаст иерархическое дерево.


serbanov

Джон, те файлы, о которых я говорю, находятся в проекте компании. Им нужно свое иерархическое дерево, но они находятся в программе под названием идеи ... вот как они обращаются к ним и смотрят, как они связаны ... Так что это не жизнеспособное решение !

Рейтинг:
0

#realJSOP

Самое первое, что я бы сделал, - это удалил все комментарии из анализируемого файла(файлов). Это очистит и упростит код, который вы используете для поиска операторов include. Вот метод, который должен сделать это (только ограниченное тестирование, но это поможет вам начать). После вызова этого метода все, что вам нужно сделать, это найти строки, которые StartWith("#include ") Построение рекурсивного метода, который вам нужен, должно быть детской игрой на этом этапе.

public void StripComments(ref List<string> lines)
{
    // remove double-slash comments
    for (int i = lines.Count-1; i >= 0; i--)
    {
        string line = lines[i].Trim();
        if (!string.IsNullOrEmpty(line))
        {
            int pos = line.IndexOf("//");
            if (pos >= 0)
            {
                line = (pos == 0) ? string.Empty : line.Substring(pos);
            }
            lines[i] = line;
        }
    }

    // remove slash-star comments

    // create one big line
    string allLines = string.Empty;
    for (int i = 0; i < lines.Count; i++)
    {
        allLines = string.Concat(allLines, lines[i]);
    }
    allLines = allLines.Trim();

    // determine if the big line starts with a slash-star
    string[] seps = new string[]{"/*"};
    bool startsWithSlashStar = allLines.StartsWith(seps[0]);

    // split the string on the slash-star
    string[] parts = allLines.Split(seps, StringSplitOptions.None);

    // Iterate the parts and remove everything that's part of a comment. This 
    // should account for nested comments as well.
    for (int i = 0; i < parts.Length; i++)
    {
        string part = parts[i];
        int pos = part.LastIndexOf("*/");
        if (pos >= 0)
        {
            part = part.Substring(pos+2);
        }
        else
        {
            if (i == 0)
            {
                if (startsWithSlashStar)
                {
                    part = string.Empty;
                }
            }
            else
            {
                part = string.Empty;
            }
        }
        parts[i] = part;
    }

    // put it all back together into one big line
    allLines = string.Empty;
    for (int i = 0; i < parts.Length; i++)
    {
        allLines = string.Concat(allLines, parts[i]);
    }
    // split the big line of semi colons, and trim off the whitespace for each line
    parts = allLines.Split(';');
    for (int i = 0; i < parts.Length; i++)
    {
        parts[i] = parts[i].Trim();
    }

    // and put the parts back into the original lines list
    lines.Clear();
    lines.AddRange(parts);
}


Предостережение-использование рекурсивного метода может вызвать проблемы в том случае, если вы анализируете большой проект в сочетании с тем фактом, что вам нужно загрузить каждый файл в оперативную память и потенциально большое количество строк при итерации найденных включений. Вы можете столкнуться с исключениями переполнения стека.

Возможно, будет хорошей идеей изменить описанный выше метод, чтобы также добавить только операторы include обратно в исходный список строк lines. Это значительно сократит потребление памяти при рекурсии файлов. Просто сделайте это в конце метода, который я опубликовал.

// if you just want the includes
var includes = parts.Where(x=>x.ToLower().StartsWith("#include "));
lines.Clear();
lines.AddRange(includes);


serbanov

Здравствуйте, извините за поздний ответ, я был занят в выходные и не смог ответить на ваше сообщение. Причина, по которой я написал свой код для части "#include", заключается в том, что наши программисты из компании имеют разные стили написания кода, а также разные шаблоны ... я мог бы сделать это проще, как ты, но я потерял бы много информации ... и я не могу себе этого позволить, мне нужно извлечь только то , что находится между"", именем заголовка ... например : from #include "my_header.h", я хочу только my_header.h в виде строки в список..

#realJSOP

Ну тогда вам также нужно разобрать make-файл(ы)для включения путей. Мой совет-найти инструмент, который уже доступен.

serbanov

Именно это я и делаю. Мне нужна только иерархия их зависимостей .. И вот я в тупике ... Я получаю информацию в словаре ... но не так, как мне нужно их печатать.

Выход, который у меня сейчас есть, примерно такой :

Я нахожу заголовок- - - & gt; помещаю его в словарь ( ключ-это заголовок, значения-это список заголовков, которые включены в этот заголовок, который я нашел) - > После этого первое значение из приведенного выше списка получает ту же "обработку", что и первый заголовок, и так далее ...

Это не тот способ, которым я хочу печатать свою информацию относительно их иерархии..