Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Рекурсия ключевых слов: Поиск и обработка включаемых файлов и переменных в текстовых файлах

Delphi , Синтаксис , Массивы

В статье рассматривается проблема рекурсивного поиска и обработки включаемых файлов и переменных в текстовых файлах на языке Object Pascal (Delphi). Мы рассмотрим существующий код и предложим решение для устранения доступа к недопустимым областям памяти (access violation), которое возникает при обработке ключевых слов, отличных от "включает".

Существующий код использует структуры данных ItemRecord, FileTree и Pages, а также рекурсивную функцию RecurseKeywords для поиска и обработки включаемых файлов и переменных в текстовых файлах. Функция использует регулярные выражения для извлечения включаемых файлов и переменных из текста файлов. Однако, при обработке ключевых слов, отличных от "включает", возникает доступ к недопустимым областям памяти.

Для решения этой проблемы, мы можем добавить проверку на существование массивов L0CodeData и L1CodeData перед доступом к ним. Кроме того, мы можем добавить проверку на существование файла, перед попыткой доступа к нему. Ниже представлен обновленный код функции RecurseKeywords:

function RecurseKeywords(pFileName: String; PageIdx: Integer; L1Index: Integer = 0): Integer;
Var
  i,z, idx, idy, idz,k: Integer;
  ChildCtr: Integer;
  ActMem: TStringList;
  s,t:string;

  function GetItems(Text: String; Category: TCategory):string;
  Var
    RegEx: TRegex;
    Match: TMatch;
  begin
    case Category of
      caIncludes:
        Match := Regex.Match(Text, '^\s*Include\s+"([0-9a-z_\-\\ :]+[\.inc|\.bas]+)"',[roignorecase]);
      caVariables:
        Match := Regex.Match(Text,'^\s*Dim\s+([a-z_#][0-9a-z_#]+)(?:_0-9a-z)*(\s+as\s+(bit|byte|word|dword|float|sbyte|sword|sdword|Long|slong|double|string|pin))',[roignorecase]);
    end;
    if match.Success then
      result := match.Groups[1].Value
    else
      result := '';
  end;

begin
  Result := 0;
  if not Assigned(Pages[PageIdx]) then Exit;
  if not FileExists(pFileName) then Exit;

  ActMem := TStringList.Create;
  ActMem.LoadFromFile(pFileName);
  idz := L1Index;    // Set Key to first item in the level 1 list
  for idy := 0 to High(Items) do begin   // scan through all items
    ChildCtr := 0;
    for idx := 0 to ActMem.Count -1 do begin
      t := trimLeft(ActMem[idx]);   // remove spaces and skip empty lines.
      if (t <> '') and (t[1] <> #39) and (t[1] <> #59) then begin
        s := GetItems(t, TCategory(idy));
        if s > '' then begin
          if not Assigned(Pages[PageIdx].L0CodeData) then begin
            SetLength(Pages[PageIdx].L0CodeData,0);
          end;
          if not Assigned(Pages[PageIdx].L1CodeData) then begin
            SetLength(Pages[PageIdx].L1CodeData,0);
          end;

          if (High(Pages[PageIdx].L0CodeData) = -1)                            // if no L0 data or
          or (Pages[PageIdx].L0CodeData[High(Pages[PageIdx].L0CodeData)].RecType<>TCategory(idy)) then   // L0 Record type <> to Item type
            SetLength(Pages[PageIdx].L0CodeData,Length(Pages[PageIdx].L0CodeData)+1);         // Create new L0 entry
          with Pages[PageIdx].L0CodeData[High(Pages[PageIdx].L0CodeData)] do begin
            RecType := TCategory(idy);
            Caption := Items[idy];
            ImageIndex := 0;
            lineNo := Idx;
            Key := idz;
          end;

          SetLength(Pages[PageIdx].L1CodeData, Length(Pages[PageIdx].L1CodeData)+ 1);
          with Pages[PageIdx].L1CodeData[High(Pages[PageIdx].L1CodeData)] do begin   // Populate the L1 Record
            RecType := TCategory(idy);
            Caption := s;
            ImageIndex := idy+3;
            LineNo := idx;
            case RecType of
              caIncludes:
                if FileExists(SourcePath+s) then begin
                  ImageIndex := 4;
                  SetLength(Pages, Length(Pages)+1);
                  Key := High(Pages);
                  Caption := s;
                  ChildCount := RecurseKeywords(SourcePath+s,Key);
                end;
              caVariables:
            end;
            ChildCount := 0;
            Inc(ChildCtr);
          end;
        end;
      end;
    end;
    idz := Idz + ChildCtr;
    if ChildCtr > 0 then
      Pages[PageIdx].L0CodeData[High(Pages[PageIdx].L0CodeData)].ChildCount := ChildCtr;
    Form1.SaveToFile;
  end;
  ActMem.Free;
  result := Length(Pages[PageIdx].L0CodeData);
end;

Также, для предотвращения доступа к недопустимым областям памяти, мы можем добавить проверку на существование файла перед попыткой загрузки его содержимого в TStringList. Обновленный код инициализации ActMem может выглядеть так:

  if not FileExists(pFileName) then Exit;
  ActMem := TStringList.Create;
  ActMem.LoadFromFile(pFileName);

В заключение, мы рассмотрели проблему рекурсивного поиска и обработки включаемых файлов и переменных в текстовых файлах на языке Object Pascal (Delphi). Мы предложили решение для устранения доступа к недопустимым областям памяти, которое возникает при обработке ключевых слов, отличных от "включает". Мы добавили проверку на существование массивов L0CodeData и L1CodeData перед доступом к ним, а также добавили проверку на существование файла перед попыткой доступа к нему.

Создано по материалам из источника по ссылке.

В статье описывается проблема рекурсивного поиска и обработки включаемых файлов и переменных в текстовых файлах на языке Object Pascal (Delphi), а также предлагается решение для устранения доступа к недопустимым областям памяти, возникающего при обработке


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




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


:: Главная :: Массивы ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-01-28 05:11:23/0.0033788681030273/0