Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.11.28;
Скачать: CL | DM;

Вниз

найти все строки в проекте, эксперт для IDE?   Найти похожие ветки 

 
antonn ©   (2010-08-19 13:19) [0]

Имеется довольно большой (по кол-ву юнитов) проект, с локализацией. Но т.к. в процессе отладки часто подставлялись строки прямо в коде (не из массива локали), то есть вероятность что где-то в юнитах остались строки "в чистом виде" и их нужно заменить. Так вот вопрос - как в проекте найти текстовые строки во всех юнитах (я про "text")? Но желательно не включая родные дельфовые :)
Есть ли какой нибудь эксперт для ИДЕ? D7 юзаю


 
Игорь Шевченко ©   (2010-08-19 13:27) [1]

в GExperts не ?

Я программу из сотни строк писал на такой предмет.


 
antonn ©   (2010-08-19 13:35) [2]


> Я программу из сотни строк писал на такой предмет.

а можно посмотреть? :)

GExperts скачал, посмотрю


 
Игорь Шевченко ©   (2010-08-19 14:01) [3]


> а можно посмотреть? :)


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


 
DVM ©   (2010-08-19 14:01) [4]

Мне кажется, в GExperts нету этого, сам как то искал, не нашел, может плохо искал


 
antonn ©   (2010-08-19 17:03) [5]

да, не нашел, сделал поиск по ", сразу вспомнил про загрузчики конфигураций из ini-файлов, про логи... получилось много :)


 
DVM ©   (2010-08-19 17:47) [6]


> antonn ©   (19.08.10 17:03) [5]

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


 
Игорь Шевченко ©   (2010-08-19 18:13) [7]

antonn ©   (19.08.10 17:03) [5]

вот как-то так, два юнита:

unit SourceReader;

interface
uses
 HSFileMapper;

type
 TSourceReader = class
 private
   FMapper : THSFileMapper;
   FCursor : PChar;
   FLineNumber: Integer;
   function GetEof: Boolean;
   function GetNextChar: Char;
   function GetFileName: String;
   function IsEndOfLine : Boolean;
   procedure ProcessEndOfLine;
   function GetNextSourceChar: Char;
   function CheckLineComment (C: Char): Boolean;
   function CheckBracketComment (C: Char): Boolean;
   function CheckOldStyleComment (C: Char): Boolean;
   function IsString (const S: string): Boolean;
 public
   constructor Create (const AFileName: string);
   destructor Destroy; override;
   function PreviewChar: Char;
   property LineNumber: Integer read FLineNumber;
   property Eof: Boolean read GetEof;
   property NextChar: Char read GetNextChar;
   //С пропуском комментариев
   property NextSourceChar: Char read GetNextSourceChar;
   property FileName: string read GetFileName;
   function NextSourceCharEx (var SpecComment: Boolean): Char;
 end;

implementation
uses
 SysUtils;

const
 SSpecComment: string = "//{";

{ TSourceReader }

function TSourceReader.CheckBracketComment(C: Char): Boolean;
begin
 Result := C = "{";
end;

function TSourceReader.CheckLineComment (C: Char): Boolean;
begin
 Result := (C = "/") and not Eof and (FCursor^ = "/");
end;

function TSourceReader.CheckOldStyleComment(C: Char): Boolean;
begin
 Result := (C = "(") and not Eof and (FCursor^ = "*");
end;

constructor TSourceReader.Create(const AFileName: String);
begin
 FMapper := THSFileMapper.Create(AFileName);
 FCursor := FMapper.Map;
 FLineNumber := 1;
end;

destructor TSourceReader.Destroy;
begin
 FMapper.Free;
 inherited;
end;

function TSourceReader.GetEof: Boolean;
begin
 Result := (FCursor >= FMapper.EndMap) or (FCursor^ = #26);
end;

function TSourceReader.GetFileName: String;
begin
 Result := FMapper.FileName;
end;

function TSourceReader.GetNextChar: Char;
begin
 Result := #0;
 if not Eof then
   if IsEndOfLine then begin
     ProcessEndOfLine;
     Exit;
   end;
 if Eof then
   Exit;
 Result := FCursor^;
 Inc(FCursor);
end;

function TSourceReader.GetNextSourceChar: Char;
begin
 Result := NextChar;
 if (Result = #0) and not Eof then begin
   Result := " ";  //Заменить конец строки на пробел
   Exit;
 end;
 if CheckLineComment(Result) or CheckBracketComment (Result)
    or CheckOldStyleComment (Result) then
 begin
   if CheckLineComment(Result) then
   begin
     //Пропустить комментарий до конца строки
     repeat
       Result := NextChar;
     until (Result = #0) or Eof;
     if not Eof then
       Result := " "; //Заменить комментарий на пробел
     Exit;
   end;
   if CheckBracketComment (Result) then
   begin
     repeat
       Result := NextChar;
     until (Result = "}") or Eof;
     Result := " "; //Заменить комментарий на пробел
     Exit;
   end;
   if CheckOldStyleComment(Result) then
   begin
     Inc(FCursor); //Пропустить звездочку
     while not Eof do
     begin
       Result := NextChar;
       if (Result = "*") and not Eof and (FCursor^ = ")") then begin
         Inc(FCursor); //Пропустить скобку
         Result := " "; //Заменить комментарий на пробел
         Exit;
       end;
     end;
   end;
 end;
end;

function TSourceReader.IsEndOfLine: Boolean;
begin
 Result := (FCursor^ = #13) or (FCursor^ = #10);
end;

function TSourceReader.IsString(const S: string): Boolean;
begin
 Result := (FCursor + Length(S) < FMapper.EndMap)
   and (StrLComp(PChar(S), FCursor, Length(S)) = 0);
end;

function TSourceReader.NextSourceCharEx(var SpecComment: Boolean): Char;
begin
 SpecComment := IsString (SSpecComment);
 Result := NextSourceChar;
end;

function TSourceReader.PreviewChar: Char;
begin
 if Eof then
   Result := #0
 else
   if IsEndOfLine then
     Result := " "
   else
     Result := FCursor^;
end;

procedure TSourceReader.ProcessEndOfLine;
begin
//TODO: Добавить поведение для файла, где строки разделены только возвратами
//      каретки.
 if FCursor^ = #13 then
   Inc(FCursor);
 if Eof then
   Exit;
 if FCursor^ = #10 then begin
   Inc(FLineNumber);
   Inc(FCursor);
 end;
end;

end.


 
Игорь Шевченко ©   (2010-08-19 18:14) [8]

unit Scanner;

interface
uses
 SysUtils, SourceReader;

type
 TLexemeKind = (lxkUnknown, lxkEof, lxkSeparator, lxkKeyword, lxkIdentifier,
   lxkNumber, lxkString, lxkPunctuation, lxkSpecComment);

 TScanner = class
 private
   function IsKeyword (const S: string): Boolean;
   function IsPunctuationChar (C: Char): Boolean;
   function IsValidIdentifierChar (C: Char): Boolean;
   function IsWhite (C: Char): Boolean;
 public
   function GetLexeme (const Reader: TSourceReader;
     var LexemeKind: TLexemeKind; IncludeSeparators: Boolean = true): string;
   function LexemeKindToString (const LexemeKind: TLexemeKind): string;
 end;

implementation

{ TScanner }

function TScanner.GetLexeme(const Reader: TSourceReader;
 var LexemeKind: TLexemeKind; IncludeSeparators: Boolean): String;
var
 C: Char;
 SpecComment: Boolean;
label
 Rescan;
begin
 LexemeKind := lxkUnknown;
 Result := "";
 if Reader.Eof then begin
   LexemeKind := lxkEof;
   Exit;
 end;
Rescan:
 C := Reader.NextSourceCharEx (SpecComment);
 if C = #0 then //Заменa концa строки на пробел
   C := " ";
 if IsWhite(C) then
 begin
   if SpecComment then
   begin
     LexemeKind := lxkSpecComment;
     Exit;
   end;
   LexemeKind := lxkSeparator;
   if IncludeSeparators or Reader.Eof then
     Exit
   else
     goto Rescan;
 end;
 if C = """" then
 begin
   Result := C;
   repeat
     C := Reader.NextSourceChar;
     Result := Result + C;
   until (C = """") or Reader.Eof;
   LexemeKind := lxkString;
   Exit;
 end;
 if IsPunctuationChar(C) then
 begin
   Result := C;
   LexemeKind := lxkPunctuation;
   Exit;
 end;
 Result := C;
 //Сначала числа
 if C in ["0".."9"] then
 begin
   while Reader.PreviewChar in ["0".."9"] do
     Result := Result + Reader.NextSourceChar;
   LexemeKind := lxkNumber;
   Exit;
 end;

 while IsValidIdentifierChar(Reader.PreviewChar) do
   Result := Result + Reader.NextSourceChar;
 LexemeKind := lxkIdentifier;
 if IsKeyword(Result) then
   LexemeKind := lxkKeyword;
end;

function TScanner.IsKeyword(const S: String): Boolean;
const
 Keywords : array[0..95] of String = (
 "abstract", "and", "array", "as", "asm", "assembler", "begin",
 "boolean", "break", "byte", "case", "cdecl", "char", "class",
 "const", "constructor", "dec", "default", "destructor", "div",
 "do", "double", "downto", "dynamic", "else", "end",
 "end.", "except", "exit", "extended",
 "false", "finalization", "finally", "function", "for",
 "high", "if", "implementation", "in",
 "inc", "inherited", "initialization", "int64", "integer", "interface", "is",
 "longint",
 "low", "message", "mod", "nil", "not", "object",
 "of", "or", "overload", "override", "packed", "pchar", "pointer", "private",
 "procedure", "property", "protected", "public",
 "published", "pwidechar", "raise", "record", "reintroduce", "repeat", "result",
 "self", "set",
 "shl", "shortstring", "shr", "sizeof", "smallint", "stdcall", "string",
 "then", "threadvar",
 "to", "true", "try", "type",
 "unit", "until", "uses", "var", "variant",
 "virtual", "widestring", "with", "while" );
var
 I : Integer;
begin
 Result := false;
 for I:=Low(Keywords) to High(Keywords) do
   if SameText(Keywords[I], S) then begin
     Result := true;
     Break;
   end;
end;

function TScanner.IsPunctuationChar(C: Char): Boolean;
begin
 Result := C in ["(", ")", "{", "}", ";", ",", "[", "]", "=", ":", ".", "+",
                 "-", "*", "/", "<", ">", "#", "$", "^", "@", """"];
end;

function TScanner.IsValidIdentifierChar(C: Char): Boolean;
begin
 Result := not ((C = " ") or IsPunctuationChar(C) or (C = #0));
end;

function TScanner.IsWhite(C: Char): Boolean;
begin
 Result := C in [ #9," "];
end;

function TScanner.LexemeKindToString(
 const LexemeKind: TLexemeKind): String;
const
 LexemeKindNames: array[TLexemeKind] of String = (
   "Unkn", "Eof", "Sep", "Kwd", "Ident", "Numb", "Str", "Punct", "Spec"
 );
begin
 Result := LexemeKindNames[LexemeKind];
end;

end.


 
Игорь Шевченко ©   (2010-08-19 18:14) [9]

{
  Модуль: HSFileMapper

  Описание: Класс, обеспечиващий создание файла, проецируемого в память

  Автор: Игорь Шевченко

  Дата создания: 07.02.2003

  История изменений:
}
unit HsFileMapper;

interface
uses
 Windows;

type
 THSFileMapper = class
 private
   FReadOnly: Boolean;
   FFileHandle: THandle;
   FFileSize: DWORD;
   FMap: PChar;
   FFileName: string;
   function GetEndMap: PChar;
 public
   constructor Create (const AFileName: string; ReadOnly: Boolean = true);
   destructor  Destroy; override;
   procedure Unmap;
   property Map: PChar read FMap;
   property EndMap: PChar read GetEndMap;
   property FileSize: DWORD read FFileSize;
   property FileName: string read FFileName;
 end;

implementation
uses
 SysUtils;

{ THSFileMapper }

constructor THSFileMapper.Create(const AFileName: string; ReadOnly: Boolean);
var
 SizeHighPart: DWORD;
 FileMapping: THandle;
const
 FileAccessMode: array [Boolean] of DWORD = (GENERIC_READ or GENERIC_WRITE,
   GENERIC_READ);
 MappingAccessMode: array[Boolean] of DWORD = (PAGE_READWRITE,
   PAGE_READONLY);
 MapAccessMode: array[Boolean] of DWORD = (FILE_MAP_WRITE,
   FILE_MAP_READ);
begin
 FReadOnly := ReadOnly;
 FFileName := AFileName;
 FFileHandle := CreateFile (PChar(AFileName), FileAccessMode[ReadOnly],
   FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
   nil, OPEN_EXISTING, 0, 0);
 if FFileHandle = INVALID_HANDLE_VALUE then
   RaiseLastWin32Error;
 FFileSize := GetFileSize(FFileHandle, @SizeHighPart);
 FileMapping := CreateFileMapping (FFileHandle, nil,
   MappingAccessMode[ReadOnly], 0, 0, nil );
 if FileMapping = 0 then
   RaiseLastWin32Error;
 FMap := MapViewOfFile (FileMapping, MapAccessMode[Readonly], 0, 0, 0 );
 CloseHandle (FileMapping);
 if not Assigned(FMap) then
   RaiseLastWin32Error;
end;

destructor THSFileMapper.Destroy;
begin
 if Assigned(FMap) then
 begin
   if not FReadOnly then
     FlushViewOfFile(FMap, 0);
   UnmapViewOfFile (FMap);
 end;
 if FFileHandle <> INVALID_HANDLE_VALUE then
   CloseHandle (FFileHandle);
 inherited;
end;

function THSFileMapper.GetEndMap: PChar;
begin
 Result := FMap + FFileSize;
end;

procedure THSFileMapper.Unmap;
begin
 if Assigned(FMap) then
 begin
   if not FReadOnly then
     FlushViewOfFile(FMap, 0);
   UnmapViewOfFile (FMap);
 end;
 FMap := nil;
end;

end.


 
Sapersky   (2010-08-19 18:47) [10]

В стандартном Find in Files есть галочка Regular Expressions... хотя я так и не понял, как их использовать для поиска строк, чтобы искало два апострофа с чем-то между ними.


 
DVM ©   (2010-08-19 19:28) [11]


> Игорь Шевченко ©   (19.08.10 18:14) [8]

в  Keywords : array[0..95] of String

по моему не все зарезервированные слова


 
Игорь Шевченко ©   (2010-08-19 20:24) [12]


> по моему не все зарезервированные слова


совсем не все. так это и писалось давно.


 
DVM ©   (2010-08-19 20:52) [13]


> Игорь Шевченко ©   (19.08.10 20:24) [12]


> так это и писалось давно.

Из очень давно зарезерверованных слов там нету "label" и "out".


 
Игорь Шевченко ©   (2010-08-19 22:13) [14]

DVM ©   (19.08.10 20:52) [13]

Вот label даже не вспомнилось, представь! И goto нету среди зарезервированных :)

Писалось под свои нужды, ограничений нет, хочется, можно поправить как угодно.


 
DVM ©   (2010-08-19 22:30) [15]


> Игорь Шевченко ©   (19.08.10 22:13) [14]


> Вот label даже не вспомнилось, представь! И goto нету среди
> зарезервированных :)

Зато в коде выше и то и другое имеется :)


 
Игорь Шевченко ©   (2010-08-19 23:13) [16]

DVM ©   (19.08.10 22:30) [15]

Уел :)



Страницы: 1 вся ветка

Текущий архив: 2010.11.28;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.009 c
2-1284144181
flasher
2010-09-10 22:43
2010.11.28
Проблема с дочерними mdi окнами


2-1284117218
Avil
2010-09-10 15:13
2010.11.28
Изменение позиции формы одной командой


2-1283663438
Делфиец
2010-09-05 09:10
2010.11.28
Kак преобразовать путь программы


2-1283771755
rnts
2010-09-06 15:15
2010.11.28
Ошибка в запросе


15-1282465841
AlexDn
2010-08-22 12:30
2010.11.28
Просветите насчет имени