Толик Панков
hex_laden
............ .................. ................

October 2025
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Толик Панков [userpic]
Lazarus, встроенный парсер командной строки.

Преамбула


В Lazarus есть довольно неплохой парсер командной строки, который (почти) работает из коробки.

Для его использования нужно создать приложение на базе класса TCustomApplication, который обладает таким функционалом. Готовый шаблон проекта имеется в комплекте. Проект --> Создать проект... и в появившемся окне выбрать тип проекта Консольное приложение:



Можно ввести параметры для генерации кода:



Основной код приложения размещается в процедуре DoRun, например, в procedure TMyApplication.DoRun;

Решил расширить пример с поиском файла по маске (копия), заодно поэкспериментировать с парсером командной строки.

Параметры будут такие:

Использование: smallfinder.exe <аргументы>
-h - эта помощь
-m <маска> - маска файла для поиска. Обязательный параметр
-d <директория> - Начальняя директория, если параметр не указан, используется текущая.
-s - включить в поиск подкаталоги


Анализ параметров командной строки


Примечание: весь код в процедуре TSmallfinder.DoRun.

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

// check if no parameters - способ из документации нихуя не сработал
if ParamCount=0 then begin
	WriteHelp;
	Terminate;
	Exit;
end;


Но далее все вроде бы пошло как надо, единственное, что параметры регистрозависимые (т.е. -d и -D программа воспринимает как разные параметры), пока не стал с этим разбираться, может после, если сильно надо будет. Длинные имена параметров не использовал, только короткие.

Вывод помощи:

//help
if HasOption('h', '') then begin
	WriteHelp;
	Terminate;
	Exit;
end;


Процедуру WriteHelp можно создать при создании нового проекта, а потом только запомнить, примерно так:

procedure TSmallfinder.WriteHelp;
begin
  writeln('Usage: ',ExtractFileName(ExeName), ' <arguments>');
  WriteLn('-h - this help');
  WriteLn('-m <mask> - file mask for search. Parameter must be!');
  WriteLn('-d <directory> - start directory. If not, use current dir.');
  WriteLn('-s - include subdirs');
end;


Маска файла:

//mask
if HasOption('m','') then begin
	Mask:=GetOptionValue('m','');
	if Mask = '' then begin
		WriteHelp;
		Terminate;
		Exit;
	end;
end;


Стартовый каталог:

//start directory
StartDir:=GetOptionValue('d','');
if StartDir='' then begin
	StartDir:=GetCurrentDir();
end;


Искать в подкаталогах:

//Include subdirs
IncludeSubdirs:=HasOption('s','');


Ну и сам процесс поиска, до кучи:

WriteLn('Start directory: ',StartDir);
lstFiles := TStringList.Create;
FindAllFiles(lstFiles, StartDir, Mask, IncludeSubdirs);
i:=0;
while i < lstFiles.Count do begin
	WriteLn(lstFiles[i]);
	inc(i);
end;
lstFiles.Free();


Естественно, все нужные переменные перечисляем в секции var процедуры TSmallfinder.DoRun

var
   Mask, StartDir:string;
   IncludeSubdirs:boolean;
   i:LongInt;
   lstFiles:TStringList;


Примеры работы


smallfinder.exe -m *.exe -d C:\Windows



smallfinder.exe -m *.exe -d C:\Windows -s



smallfinder.exe -m *.exe



Ссылки


Мануал по обработке параметров командной строки
Пример целиком на GitHub

Это репост с сайта http://tolik-punkoff.com
Оригинал: https://tolik-punkoff.com/2022/11/27/lazarus-vstroennyj-parser-komandnoj-stroki/

Tags: ,
Comments
(Anonymous)
Господь Иисус и святые угодники!

Кому нужно это говно мамонта? Красно-черное дерево перевернёшь?

Re: Господь Иисус и святые угодники!

Мне нужно. Работает - значит не говно. Про дерево ничего не знаю. Черное вроде есть, из него мебель делают, красное тоже есть, а чтоб сразу оба два, ну я не настолько в ботанике шарю.

Re: Господь Иисус и святые угодники!

Ньет, мне такого матана точно не надо, у меня аж голова заболела. Благо, с древовидными структурами сталкивался раз в жизни, переписывая кривую программу для страховой компании. У них там древовидный отчет был по страховым случаям, ну примерно так:
0. Страховой случай
1. Травма
1.1. Транспортная травма
1.1.1. Автомобильная
1.1.2. Железнодорожная
1.1.3. Авиационная
1.2. Электротравма
1.3. Укус животного
1.3.1. Укус бродячей собаки
1.3.2. Укус хозяйской собаки
1.3.3. Укус змеи
2. Пожар
...
Ну и т.д. Тетки долго мучились с родной программой, которую как раз какой-то адепт матана писал, со всякими как-раз там правильно реализованными деревьями и очень сложными SQL-таблицами, с первичными, вторичными ключами. Все по науке и все тормозило. Ну ключ же не должен содержать информации об объекте, он же должен ключом быть.

Я сделал плоскую табличку из трех колонок:
Строковый ключ|Случай|Признак вводимости
Строковый ключ выглядел как 1, 11, 111, 112, ну ты понял принцип, и все промежуточные итоги в огромной таблице вдруг моментом начали легко и быстро собиралось в нужные кучки Like'ом, и моментально считалось.

Более я, слава Ктулху, с деревьями напрямую не сталкивался.