Сэр Серж aka Sir Serge (Сергей Лебедев) - official site
Статьи и заметкиРасчетыО сайте

Внимание!

Статья очень старая, и имеет чисто историческую ценность. Многие вещи давно делаются не так, как в ней описано!

Lazarus :: Resurrection :: прикладная кадаврология

«Иисус сказал … : Lazarus умер; и радуюсь за вас, что Меня не было там, ...; но пойдем к нему.

Тогда Фома ... сказал ученикам: пойдем и мы умрем с ним.

…Иисус, придя, нашел, что он уже четыре дня в гробе.

... Он воззвал громким голосом: Lazarus! иди вон.

И вышел умерший, обвитый по рукам и ногам погребальными пеленами, и лице его обвязано было платком. Иисус говорит им: развяжите его, пусть идет

Иоанн, гл. 11

«Ковыляй потихонечку,
а меня ты забудь.
Отрастут твои ноженьки -
проживёшь как-нибудь»

Дворовая песня

Когда-то, в давние-давние времена, когда иностранная «культура» только-только проникала на необъятные просторы павшего под рукой диссидентства Советского Союза, на смену привычному классическому инструментарию программирования наследия прошлого, состоящего отнюдь не из C или бейсика, а в основном из фортрана и PL, пришло новое. И новое это для многих начиналась с компиляторов и сред программирования Borland - при этом кто-то ориентировался на модность и коммерческую востребованность - fox, С и С++, а кто-то - на рациональность и быстроту. И стал популярен Turbo Pascal )) Причем, со временем он стал не только выбором любителей экзотики и покодить, но практически официальным языком обучения основам программирования в ВУЗах и многих других учебных заведениях.

Turbo Pascal развивался, совершенствовался, и … терял корни своего происхождения. То, до чего он эволюционировал сегодня, синтаксически и по сути гораздо ближе к C++, чем к Виртовскому классическому Паскалю, и вполне достойно называться как-нибудь... без упоминания Паскаля вообще.

Кому интересна история и общественное мнение, может ознакомиться со вполне годной статьей, посвященной языку программирования Паскаль на Лурке: lurkmore.ru/Паскаль

Лично для меня Turbo/Borland Pascal достаточно длительное время был вполне рабочим инструментом по следующим причинам:

Позднее были Delphi, C++ Builder; пока кому-то там не пришла в голову мысль о том, что Россия наконец-то должна соблюдать законодательство об авторском праве, сиречь о необходимости для пипла заплатить держателям копирайта за использование их коммерческого программного продукта путем репрессий, и смена характера работы, постепенно от технических расчетов перешедшего практически в системное администрирование, где действо программирования превратилось если не в короткие, то в редко происходящие эпизоды.

Поскольку держать на своем компьютере интерпрайз стоимостью тыщ под 80 стало рискованным мероприятием, да и программные среды Borland начали мигрировать из под одной торговой марки под другую и стали превращаться в надстройки над .NET SDK фирмы Microsoft, при этом практически утратив контекстную справочную систему, интерес к post-Borland продуктам у меня погас, а всякие там линуксы заставили искать другие инструментальные возможности создать что-либо.

То есть, я хочу сказать что: я видел, каким был FreePascal практически в начале своего появления; Я видел, чем был Lazarus в начале своего появления; года три назад я пытался его применить для реального проекта; проект на Lazarus был написан, просуществовал in production около года и был безжалостно переписан и на Visual C# и на JAVA. Причиной послужило периодическое блокирование GDI Windows после запуска основной программы проекта то ли из за какой-то моей мелкой ошибки, то ли из за багов библиотек lazarus'a - проявлялось это в том, что ни одна программа на lazarusе или delphi не могла запуститься до перезагрузки ОС. В итоге: JAVA-версия была похоронена, не дойдя до полностью отлаженной реализации из-за поистине потрясающих затрат оперативной памяти и медленности, а версия на C# нормально работает и до сих пор.

Мне категорически не нравится синтаксис паскаля, особенно в реализации delphi.

Сделайте ему наконец case sensitive для переменных и операторов, замените «:=» на «=», одинарные кавычки на двойные, «begin» и «end» на фигурные скобки; поставьте обязательными круглые скобки вокруг условного выражения «if», ликвидируйте «then» (оно мне почему-то мозолит глаза и звучит как «бля» в обыденной речи), сделайте Си-шный for и... будет С++, практически. Да, уберите из названия слово pascal. )) Что самое смешное, все это, и более того - есть в C#, но... Абсолютная королевская воля Microsoft, мать ея... То есть, абсолютная привязка к Windows. И категорически не верится в то, что «сыр бесплатный» от этой компании в виде VS Express Edition будет существовать неограниченно долго.

Тем не менее, «на посмотреть» очередные релизы lazarus я время от времени вынимаю и вяло разглядываю медленнотекущую эволюцию.

На сегодня я могу, кажется, поздравить тех, кто долго ждал технической пригодности этого проекта для реализации своих программерских задумок. Вэлкам! FPC 2.7.1 + Lazarus SVN 33300 в сборке CodeTyphon 2.30; Вещь, которая (наконец то, десять лет каких то прошло) может печатать кириллицу в текстах программ на принтере из под linux. И это даёт неиллюзорную надежду, что и собственные программы, теперь смогут нормально пользоваться объектом принтера, его канвой и всем прочим, как написано в классических дельфовых учебниках. Раньше в этом отношении был полнейший облом. (К слову сказать, поддержка нацсимволики UTF в редакторе fp под линуксами таки не работает и по сей день - он их не то что напечатать не сможет, а отобразить на экране не в состоянии). Когда в lazarus появилась правильная печать кириллицы - к сожалению, не уследил. Но в начале года еще IDE Lazarus кириллицу не печатал.

Итак, проинсталлируем и, пусть идёт.

При инсталляции, пользователям Debian и подобных ему, стоит не забыть поставить необходимые системные библиотеки, для этого есть специальный пункт в меню. Их в дефолтной инсталляции системы отсутствует довольно изрядное количество. И на всякий случай, руками поставьте GDB, также перед установкой. Ставить lazarus/CodeTyphon необходимо исключительно из-под рута, а в Windows - с административными правами (в «7» это означает запуск от лица администратора)!

Если вы, пользователь, не truъ программер, то есть у вас монитор по вертикали менее чем 1024 пикселей, то под Windows XP окна не полностью поместятся на экране, а то и окажутся за его пределами. Корректируется проблемка в пункте меню «Сервис-Параметры-Окружение-Окно», для каждого нужного окна можно задать геометрию, после чего все это сохранить. По приложению к строке меню, редактору и остальным, параметр «Взять параметры оконного менеджера» приведут к тому, что они окажутся в квадратных окошках размерами приблизительно с окно редактирования формы, высветившимся при первом запуске. Поэтому так лучше, наверное, не делать.

При первом запуске под линуксом lazarus не может правильно определить положение своих библиотек - убрать последний подкаталог в предлагаемой строке.

При запуске под Windows lazarus в упор не видит отладчика GDB. Поэтому, надо его прописать вручную через «Сервис-Параметры-Отладчик». Тип отладчика - Gnu Debugger (GDB), местоположение - c:\codetyphon\binGDB\win32\gdb.exe

Всё, что сказано выше, относится к релизу CodeTyphon. Можете, конечно, добывать тушку и из других источников, но именно в этом будет сразу поставлено много полезных и не очень компонент программирования, включая работу с directX, OpenGL, MIDI и проч. - с исходниками и примерами, и процесс установки полностью автоматизирован, в отличие от вдумчивой ручной сборки из официального дистрибутария. Ну, и из официального депозитария Debiana вам поставится суровая древняя версия lazarus 0.9.28, у которой проблемы с печатью кириллицы на принтере )).

Итак, процесс пошел. )) Я не буду учить вас программировать. Очень надеюсь, что delphi вы видели и с основами знакомы, иначе путь вам к книжкам. В отличие от прототипа, самодокументирование lazarus'a весьма и весьма убого, прилично документирован только FreePascal, да и то - на английском и немецком; и справочная система подключается тоже от него же (скачивается и ставится вручную). По дефолту у вас будет нечувствительная к контенту ссылка на wiki lazarus и html-справочник в интернете, на сайте freepascal.org. Если кто имел дело, тот помнит, что сей ресурс достаточно часто находится в состоянии, близком к полному падению, а то и вообще недоступен. Поэтому, если собрались работать серьёзно - выкачайте оттуда все доступные helpы и сохраните их у себя на компьютере. Пригодится обязательно рано или поздно.

Второй особенностью, которая обязательно сломает голову имеющим опыт работы на delphi, является то, что (а) объекты lcl отличаются от объектов vсl не только по внутренней реализации, но часто - по интерфейсу. Функции и константы могут иметь другие имена и(или) располагаются в других Unit-ах и (б) lazarus работает с файлами в кодировке UTF-8 и оперирует строками в кодировке UTF-8, имеющими тип utf8string... на сегодняшний день безусловно приравненный к ansistring и string.

В первую очередь, для программиста это означает стальные рамки поведения: для вас больше не должно существовать переменных и констант типа char и нет никакой возможности выбрать символ по индексу в строке как в массиве символов. И вы не имеете права применять никакие функции для типов String/AnsiString с указанием позиции символа в строке, задаваемого вами «вручную», если хотите корректных результатов. То есть, код:

Var
   s,s1:utf8string;
   c:char;
begin
   s:='Это моя строка';
   c:=s[3];
   s1:=copy(s,5,3);
end;

абсолютно неверен. В переменной 'c' вы не получите русское 'о'. И в s1 будет нечто неожиданное, но совершенно не ожидаемая подстрока 'моя'. Почему? Потому что это UTF-8. Все разъяснения по поводу того, как там кодируются символы национальных алфавитов - см. в соответствующем RFC и описаниях по интернету - много их. А нам предстоит просто с этим всем работать.

И первое, с чем мы скорее всего будем иметь дело - это имена файлов с использованием национальных символов, полученные с разных диалоговых окон или заложенные как константы/переменные в самом тексте программы.

Практически все необходимые для этого функции имеются в unit fileutil (components/lazutil/fileutil.pas)

Среди прочего:

UTF8FileHeader = #$ef#$bb#$bf;

Это так называемый BOM - Byte Order Mask, который может присутствовать в текстовых файлах с кодировкой UTF8, а может и не присутствовать. К этому моменту мы еще вернемся, когда будем читать файлы с UTF8 содержимым, пока просто принимаем к сведению, что здесь это есть.

function NeedRTLAnsi: boolean;

возвращает true, если системная кодировка не UTF-8.

procedure SetNeedRTLAnsi(NewValue: boolean);

принудительно устанавливает значение, возвращаемое предыдущей функцией

function UTF8ToSys(const s: string): string;
function SysToUTF8(const s: string): string;

более «продвинутые» версии функций UTF8ToAnsi и AnsiToUTF8 из модуля system (то, что в system можно применять и в «чистом» fpc, без библиотек lcl), но, соответственно, зависящие от корректности установленного widestringmanager и «добавляющие больше двоичного кода в программу». По существующему тексту библиотек из первого просто вызывается второе для linux, c незначительной косметикой для windows|windows CE, так что...

function ConsoleToUTF8(const s: string): string;

Преобразует строки в OEM кодировке в UTF-8 (для использования с некоторыми Windows-функциями)

function UTF8ToConsole(const s: string): string;

Преобразует строки в utf8 в кодировку системной консоли (используется совместо с write и writeln)

Давайте не забывать, что в «русской» Windows консоль имеет кодировку, отличную от системной. Соответственно - системная кодировка - ANSI (cp1251) (SYS в терминах этих функций), а кодировка консоли - OEM (cp866). Поэтому стараемся последние четыре функции применять правильно.

Функции для операций с файлами. Являются полными аналогами соответствующих ANSI - функций, но соответственно работают с именами файлов и каталогов в UTF8. В подавляющем большинстве перечисленного легко заменяются вложенным вызовом UTF8ToSys() в аргумент соответствующей ansi-функции и именно так и реализованы.

function FileExistsUTF8(const Filename: string): boolean;
function FileAgeUTF8(const FileName: string): Longint;
function DirectoryExistsUTF8(const Directory: string): Boolean;
function ExpandFileNameUTF8(const FileName: string): string;
function ExpandUNCFileNameUTF8(const FileName: string): string;
function ExtractShortPathNameUTF8(Const FileName : String) : String;
function FindFirstUTF8(const Path: string; Attr: Longint; out Rslt:TSearchRec): Longint;
function FindNextUTF8(var Rslt: TSearchRec): Longint;
procedure FindCloseUTF8(var F: TSearchrec);
function FileSetDateUTF8(const FileName: String; Age: Longint): Longint;
function FileGetAttrUTF8(const FileName: String): Longint;
function FileSetAttrUTF8(const Filename: String; Attr: longint): Longint;
function DeleteFileUTF8(const FileName: String): Boolean;
function RenameFileUTF8(const OldName, NewName: String): Boolean;
function FileSearchUTF8(const Name, DirList : String; ImplicitCurrentDir:Boolean = True): String;
function FileIsReadOnlyUTF8(const FileName: String): Boolean;
function GetCurrentDirUTF8: String;
function SetCurrentDirUTF8(const NewDir: String): Boolean;
function CreateDirUTF8(const NewDir: String): Boolean;
function RemoveDirUTF8(const Dir: String): Boolean;
function ForceDirectoriesUTF8(const Dir: string): Boolean;
function FileOpenUTF8(Const FileName : string; Mode : Integer) : THandle;
function FileCreateUTF8(Const FileName : string) : THandle; overload;
function FileCreateUTF8(Const FileName : string; Rights: Cardinal) : THandle; overload;

Функции, имеющие отношение к переменным окружения:

function ParamStrUTF8(Param: Integer): string;
function GetEnvironmentStringUTF8(Index: Integer): string;
function GetEnvironmentVariableUTF8(const EnvVar: string): String;
function GetAppConfigDirUTF8(Global: Boolean): string;
function GetAppConfigFileUTF8(Global: Boolean; SubDir: boolean = false):string;

Ну и остальное:

function SysErrorMessageUTF8(ErrorCode: Integer): String;

Функции для операций со строками содержатся в модуле lazutf8 (components\lazutils\lazutf8.pas)

function NeedRTLAnsi: boolean;
procedure SetNeedRTLAnsi(NewValue: boolean);
function UTF8ToSys(const s: string): string;
function SysToUTF8(const s: string): string;

опа. Они не кажутся ли вам знакомыми? Занимательно. Троекратно дублированный код (+ unit lclproc)? И что будет вызываться при одновременном использовании unit”ов? Ну что ж...

function UTF8CharacterLength(p: PChar): integer;
function UTF8Length(const s: string): PtrInt;
function UTF8Length(p: PChar; ByteCount: PtrInt): PtrInt;
function UTF8CharacterToUnicode(p: PChar; out CharLen: integer): Cardinal;
function UnicodeToUTF8(u: cardinal; Buf: PChar): integer; inline;
function UnicodeToUTF8SkipErrors(u: cardinal; Buf: PChar): integer;
function UnicodeToUTF8(u: cardinal): shortstring; inline;
function UTF8ToDoubleByteString(const s: string): string;
function UTF8ToDoubleByte(UTF8Str: PChar; Len: PtrInt; DBStr: PByte): PtrInt;
function UTF8FindNearestCharStart(UTF8Str: PChar; Len: integer; BytePos: integer): integer; 
// find the n-th UTF8 character, ignoring BIDI
function UTF8CharStart(UTF8Str: PChar; Len, CharIndex: PtrInt): PChar;
// find the byte index of the n-th UTF8 character, ignoring BIDI (byte len of substr)
function UTF8CharToByteIndex(UTF8Str: PChar; Len, CharIndex: PtrInt): PtrInt;
procedure UTF8FixBroken(P: PChar);
function UTF8CharacterStrictLength(P: PChar): integer;
function UTF8CStringToUTF8String(SourceStart: PChar; SourceLen: PtrInt):string;
function UTF8Pos(const SearchForText, SearchInText: string): PtrInt;
function UTF8Copy(const s: string; StartCharIndex, CharCount: PtrInt): string;
procedure UTF8Delete(var s: String; StartCharIndex, CharCount: PtrInt);
procedure UTF8Insert(const source: String; var s: string; StartCharIndex:PtrInt);
function UTF8LowerCase(const AInStr: string; ALanguage: string=''): string;
function UTF8UpperCase(const AInStr: string; ALanguage: string=''): string;
function FindInvalidUTF8Character(p: PChar; Count: PtrInt; StopOnNonASCII: Boolean=false): PtrInt;
function ValidUTF8String(const s: String): String;
procedure AssignUTF8ListToAnsi(UTF8List, AnsiList: TStrings);

Функции сравнения:

function UTF8CompareStr(const S1, S2: string): Integer;
function UTF8CompareText(const S1, S2: string): Integer;

Теперь, как этим всем пользоваться. Примерчик из lazarus wiki. Перевода на русский там, конечно же, нет.

Считываем из строки N-й символ:

uses lazutf8;
...
var
  AnUTF8String, NthChar: string;
begin
  NthChar := UTF8Copy(AnUTF8String, N, 1);
end;

Остальные примеры в Wiki опираются, мягко говоря, на костыли предыдущих версий. Да, можно при особом желании и понимании применять обычные строковые функции, но лучше этого не делать, если есть специальные для utf-8 - чтобы не запутаться.

Из особенностей работы со строками utf-8 обязательно следует отметить, что любая ошибка в кодировке после выхода из специализированных функций utf8 преобразования или манипуляции со строками вернёт вам пустую строку - так написано в wiki; на самом деле часть функций работает, «мусор» в строке оставляя без внимания, и только функции преобразования при случае заменяют странные символы на вопросительные знаки.

А что делает функция ValidUTF8String? Она формально преобразует порченую строку с UTF8 в синтаксически правильную, при этом вместо нераспознанных байтов, не проходящих под определение «печатных» символов ставится решеточка и десятичный код этого байта. При этом сама использует для поисков предыдущую в списке функцию - FindInvalidUTF8Character. Как именно она это делает - смотрите в исходниках, ибо функция явно техническая и не для общего применения и работает с указателями.

Таким образом - у нас нечем «из коробки» проверить корректность строки UTF8. У нас нечем «из коробки» привести порченую строку UTF8 в нормально читабельный вид путем вымарывания поврежденных символов, у нас не предусмотрено стандартных средств убрать из строки сигнатуру BOM.

Если вам заблагорассудится читать текстовый файл с UTF8 чисто паскалевским способом, то не забываем об BOM - метке Byte Order Mask. Если таковая присутствует в файле, то она благополучно считается в ваши строки и после подсовывания такой строки в функции для utf8 превосходно будет посчитана за ошибку кодировки, либо пропущена без изменений. И надо понимать, что кроме нормальной позиции в начале файла, в силу некоторых причин этот маркер может оказаться в любом его месте, да еще в нескольких экземплярах. К слову говоря, нормально расправляться с BOM (то есть, игнорировать его при чтении файла), из попавшегося мне умеют только потоковые библиотеки .net; всё остальное, включая JAVA, этот префикс не понимает и оставляет в строках as is.

поэтому читаем файл с текстом в utf-8 как то так:

uses fileutil;
var
  t:TextFile;
  s:utf8string;
  bom:PtrInt;
begin
  AssignFile(t,UTF8ToSys('имяфайла.txt'));
  reset(t);
  while not(eof(t)) do
  begin
    readln(t,s);
    repeat
      bom:=pos(s,UTF8FileHeader);
      if (bom<=0) then break;
      s:=Delete(s,bom,length(UTF8FileHeader));
    until false;
    MyProcessingForReadedString(ValidUTFString(s));
  end;
  CloseFile(t);
end;

Кроме всего прочего, в файле components/lazutils/lazutf8classes.pas обнаружены utf-8 версии классов TFileStream и TStringList; изменения касаются только работы с именами файлов при чтении и записи в поток, всё остальное поведение унаследовано.

А как же WideString? А как же автоматическое преобразование?

во-первых, для автоматического преобразования нужен widestring manager. А во вторых, даже в этом случае автоматика может не работать. Wiki утверждает, что перед тем, как использовать функции преобразования из системной кодировки в utf8 и наоборот, а также в WideString в linux, нужно включить cwstring в качестве первого модуля в списке uses. А в третьих - что вы будете делать с WideStrings? Разве что, при необходимости передавать их в dll .net и другие вендовые библиотеки?

Как официально объявлено, базовые библиотеки FreePascal кодировку UTF8 и любой другой юникод не поддерживают ни в каком виде и со строками utf8 не работают. На что и ориентируемся.

Вторая больная тема этой среды программирования - отладчик.

Программист, разбалованный возможностями отладчиков Delphi, Java, Visual Studio может оказаться в глубоком недоумении перед примитивизмом предлагаемого. Фактически, вы можете только:

Ну и как? Вас перечисленное не пугает? Не пугает полное отсутствие литературы и необходимость стартового порога, требующего от вас сплошь и рядом рыться в чужом исходном коде, для того чтобы понять, что задумали его творцы? Тогда вперед! Пусть идёт!

Barnaul, RF, 11.11.2011


Всего комментариев: 18

Sir Serge OC: Windows 7   2011-11-12 16:40:01


Кстати, насчет литературы

Можно начать с этого:

[ ccылка ]

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

Ну и, наконец, существует фундаментальный труд аж на 750 страниц
под названием "Lazarus the complete guide", который можно купить за 60$ за бугром. Книжка должна быть хорошей, если судить по страничкам на сайте издателя (там по паре страниц с начала каждой главы представлено). В спираченном виде найдено не было.


Sergej_Latvia OC: Windows XP   2012-02-08 17:42:42


да, с книгами полная засада. я вот даже задумался, что практичнее: купить "Lazarus the complete guide" за 50 евро или Deplhi XE2 Sterter за 200 евро. К делфи хоть книг накачать нахаляву можно.


Sir Serge OC: Windows 7   2012-02-08 19:05:05


Практичнее поставить MS Visual Studio Express Edition для C#. Если не нужна кроссплатформенность, то мощь и отличная продуманность библиотек .NET, та также удобство языка и среды программирования, вкупе с наличием нормальной литературы для любого уровня развития, могут позволить вам творить код в 4-6 раз быстрее.


Sir Serge OC: Windows 7   2012-02-08 19:24:19


ВНИМАНИЕ! ВАЖНОЕ ДОПОЛНЕНИЕ К ТЕКСТУ СТАТЬИ!

Поскольку выявилось замечательное явление - а именно, что в сочетании FPC 2.7.1 + Lazarus 0.9.31 напрочь поломаны все функции преобразования из строк системной кодировки в UTF8 (либо не действуют, либо кодируют например из cp866 в cp1251 вместо UTF8), товарищи c сайта freepascal.ru продемонстрировали наличие вполне адекватно работающего unit`a (расположен в lazarus/components/lazutils), имя которому lconvencoding. Эта замечательная библиотека содержит в себе функции явного преобразования кодировок, не полагающиеся на установки инициализатора RTL, что правильно.

Среди прочего - функции:

cp1251toUTF8 - UTF8tocp1251
cp866toUTF8 - UTF8tocp866
KOI8toUTF8 - UTF8toKOI8

решающие все насущные проблемы декодинга русского языка, и функции:

UTF8BOMtoUTF8 - UTF8toUTF8BOM

решающие проблемы с чортовой меткой принадлежности файла к UTF8, а также универсальную функцию ConvertEncoding(s, from, to)

Так что не все так плохо, как казалось. Всего то найти недокументированный технический unit и пользоваться :)


Sergej_Latvia OC: Windows XP   2012-02-08 21:44:33


>>Практичнее поставить MS Visual Studio Express Edition C#.

Согласен на 100%, тем более, что коссплатформенность не нужна. Но для моего проекта крайне желательно усложнить его взлом. И возможность работы без установки доп. софта (.NET фреймворка). Выбор пал пока на Лазарус, если можете чего посоветовать другого - буду благодарен!
(Проект: простенькая морда к небольшой локальной несерверной БД (желательно SQLite), под Win, поддержка UTF8 или UTF16.)


Sir Serge OC: Windows XP   2012-02-09 09:02:10


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

Либо Qt+MinGW+какая нибудь нормальная среда с адекватной поддержкой отладки и инструментария qt; NetBeans например.
.dll-ы придется тащить за собой.

Либо Qt+Visual C++, но это требует коммерческой версии Visual Studio (плагины в Express не интегрируются). Теоретически, qt можно вкомпоновать в единый exe c вашей задачей, но скорее всего, опять таки dll-ы придется тащить с собой.

Либо все таки злощастный Лазарус :). Несмотря на все его недостатки и баги, требуемое сделать на нем вполне можно. Но придется в иных случаях повозиться. И для меня, например, возня с ним как то не вызывает удовольствий. Здесь получается интересная картинка - либо пользоваться официальным релизом, давностью в год-два, либо стоически обходить сюрпризы и периодические глобальные поломки функционирования версий SVN; впрочем и в офф релизе, imho багов предостаточно. ))

Ну а почему я бы не стал связываться с Embarcadero Delphi, особенно со Starter - это:

1) Своеобразная лицензия с ограничением коммерческого распространения (!!!)
2) Если политики не изменились, то IDE этой версии скорее всего исключает целиком и полностью установку на Палитру каких либо собственных или сторонних компонентов и пакетов; для дельфообразных это существеннейший минус.
3) Цены Embarcadero imho совершенно неадекватны. В два-три раза выше по сравнению с аналогичными (и большими по функционалу) продуктами MS например.
4) По сравнению с распространенной литературой по Delphi 3-5-7-2005 Эмбаркадерские версии имеют столь же существенные различия, что и Лазарус от этих версий Delphi; Стоит ли связываться?


Sergej_Latvia OC: Windows XP   2012-02-09 14:51:49


Спасибо за советы, попробую таки на Лазарусе, все-таки в юности на Турбо Паскале немного писал, ностальгия. С++ для меня, если честно, сложноват, я фокспрошник-прикладник (уже пару лет как бывший к тому же).

По поводу Дельфи:
1) да, в курсе, прибыль д.б. не более 1000$ в год.
2) этого не знал, спасибо. вообще у них очень мне не понравилось, что нельзя Starter триал-версию скачать и реально посмотреть, что она может, что нет, т.к. описание весьма размыто. Стартера даже в торрентах нет! И они еще борятся за звание ...
3) Полностью согласен, цены неадекватны.
4) Да, действительно, по XE, XE2 почти ничего нет.


ALeksey OC: Windows 7   2012-12-10 09:46:20


Как корректно работать с файлом в пути , или в имени которого есть буквы других алфавитов (не рус и анг.)?
Например: `C: é 1.jpg` взять корректно для него FileAgeUTF8()?


Sir Serge OC: Windows 7   2012-12-10 10:27:36


>> Как корректно работать с файлом в пути , или в имени которого есть буквы других алфавитов (не рус и анг.)?

Степень корректности зависит от вашей операционной системы. Наиболее "корректны" те ОС, у которых case sensitive имена файлов - aka linux разных сортов. Т.е. операционной системе глубоко пофиг, то в нее передано, если вы кодировки совместили правильно - файл будет найден и обработан, к какой бы кодовой странице не принадлежали символы из его имени. Даже если они не отображаются в текущей кодовой странице в консоли.

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

Т.е., в ответе на ваш вопрос - корректно - никак )) - исключая случаи, когда у вас таки установлена кодовая страница языка, к которому принадлежит ваш символ.

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

Наглядный пример - на файловой системе NTFS под линуксом в принципе можно создать файл с именем "PRN:", ибо это не противореит правилам нэйминга этой операционной системы и кодовой странице UCS2, в которой работает NTFS. В случае, если файловая система с таким файлом попадет в поле зрения Windows, это может закончиться катастрофой ))

ЗЫ. Я намеренно не трогаю лазарус, ибо к нему это отношения не имеет. Это - проблема операционной системы.


Алексей OC: Windows 7   2012-12-10 13:48:38


Хорошо, но простой пример:
Пытаюсь узнать дату изменения файла в папке:
C: é - французский символ.
файл mydoc.doc

Сама ос - отображает без проблем.

А у меня - не получается FileAgeUTF8 - дает -1.
Может надо пробовать различные utf8decode и т.д?


Sir Serge OC: Windows 7   2012-12-10 14:00:23


>> FileAgeUTF8 - дает -1.

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

>> Может надо пробовать различные utf8decode и т.д?

Угу, принудительным преобразованием из UTF8 во французскую кодовую страницу может быть что нибудь получится. Если есть такая функция. Посмотрите, может быть удастся сделать конверсию UTF8 в UCS2 (unicode) и уже потом - в то что нужно. Или напишите свой декодер. Но вообще ситуация аномальная для операционной системы. Отображать то кстати, может и отображает, а вот из командной строки например, или при отображении свойств объекта может не находить файл. В MS DOS, помнится, тоже была такая фишка, как "истинное имя файла", когда оно не соответствовало тому, что выдается по команде DIR.

Ставьте точку останова и анализируйте полученные от системы имена побайтно, что ли. Очень проясняет ситуацию.


Sir Serge OC: Windows 7   2012-12-10 14:02:39


Да, и функцию в таком случайте пользуйте FileAge, которая без UTF, а так то примерно:

function FileAgeUtf8(name):....
begin
result:=FileAge(UTF8ToSys(name));
end;

(смотрите исходники)


Алексей OC: Windows 7   2012-12-10 14:46:28


Хорошо, буду смотреть.

Но! Функция FileSize() - СРАБАТЫВАЕТ и возвращает истинный размер файла в байтах.
Получается, что FileAge - не работает, а FileSize - работает.
То есть, видимо возможно корректно работать с такими файлами.


Sir Serge OC: Windows 7   2012-12-10 14:59:57


Версия то лазаруса какая? Надеюсь, не на fpc 2.7.1?
А то в этом случае поведение с функциями конверсии вообще труднопредсказуемо - многие не работают, как должны. Увы, правильное поведение смотрим на официальном релизе 2.6.0 + 1.0.4


Алексей OC: Windows 7   2012-12-10 15:04:26


Да - официальный релиз 2.6.0 + 1.0.4


Мария OC: Windows 7   2013-09-29 20:28:28


Добрый день! У меня такой вопрос: при запуске программы из лазаруса, выдаётся окно, где сказано проверить наладчика. Наладчик к порядке (gdb). Если открывать файл просто из библиотеки (т.е. не открывая лазарус), то всё работает. ПОДСКАЖИТЕ, ЧТО НУЖНО МНЕ СДЕЛАТЬ,ЧТОБЫ В ЛАЗАРУСЕ МОЖНО БЫЛО ПРОВЕРЯТЬ ПРОГРАММУ?!
Спасибо заранее.


Sir Serge OC: Windows 7   2013-09-30 08:54:07


Мария, данных, чтобы помочь вам, совершенно недостаточно.

Обычно, сообщение о невозможности запуска отладчика в лазарусе, связано с двумя моментами:

1) Неверно указан путь к отладчику, т.е. файл, на который указывается строка в диалоге Сервис -> Параметры -> Отладчик -> Общие (На кнопке должно быть указано "отладчик GDB", а в поле ниже (под кнопкой) - полное имя файла этого самого GDB, с полным путём до него.

2) Вы указываете НЕ ТОТ GDB, который входит в комплект вашего лазаруса. Каждая версия лазаруса работает только с определенными версиями GDB. Номер "поставить самый новый GDB и будет здорово" - не проходит

3) У вас возможно очень старая версия лазаруса или он некорректно установлен. У некоторых старых лазарусов были нерешаемые проблемы с отладчиком.


Дмитрий Белькевич OC: Windows X   2016-08-02 03:01:20


К слову - в FPC 3.0.0 появился режим DelphiUnicode. Строки по умолчанию становятся UTF16, проблем меньше. Лазарь развивается, хоть и не так активно как Делфи.

Commented by Sir Serge:

Без восторга отношусь к принудительным режимам совместимости с Delphi в FPC. К тому же, помянутое вами, более чем полностью несовместимо с Лазарусом как таковым. Другое дело, что с появлением 1.6, привязанного к компилятору 3х, RTL перевели в default utf8, что действительно многое упростило, но и добавило принципиальных несовместимостей с недостаточно продуманными приемами работы со строками из старого кода. Кстати, в треде, посвященном вопросу, почему для лазаруса был выбран utf8, а не 16-битный уникод, один из отцов основателей прямо заявил, что в связи с дурной идеей и реализацией в Delphi utf16 развелось потрясающее количество кода работы со строками utf16, авторы которого не понимают принципов кодировки и работы с суррогатными парами, так utf8 заставит писать более правильный код


Текст опубликован: 2011-11-11

Последние изменения текста: 2011-11-11


Вы можете добавить свои комментарии.

Комментарий появится на сайте только после того, как он будет проверен администрацией на запрещённую законодательством информацию.

Для возможности внесения комментариев в браузере должна быть включена поддержка JavaScript. Реклама и ссылки на сайты, не относящиеся к делу, являются прямым основанием удаления комментария. Поля "E-mail" и "WWW" обязательными для заполнения не являются, поле E-Mail не публикуется. Если хотите просто что-то написать автору статьи, без публикации на сайте - воспользуйтесь специальной формой под пунктом меню "О сайте". Администрация оставляет за собой право публиковать или не публиковать адреса, введенные в поле www, а также при необходимости редактировать текст вашего сообщения. Ответы на ваши сообщения по введенному вами E-mail автоматически сайтом не высылаются. Теги PHPBB и HTML не действуют.


Ещё тексты по этой теме:

Отображение графики SVG, получаемой со скрипта на сайте (2019-04-29/2019-04-29)
64-битный компилятор MinGW + NetBeans 8.2. Установка под Windows 10 x64 (2017-11-06/2017-11-06)
Представление о времени в операционных системах и языках программирования (2016-05-11/2016-05-11)
Использование строк UnicodeString и маркированных кодовой страницей AnsiString/RawByteString в приложениях Lazarus/LCL (2012-12-14/2012-12-14)
Символы и строки в Unicode-версиях FreePascal (2012-07-19/2012-07-23)
Национальный вопрос в C/C++ (2011-12-09/2011-12-09)
Халява, сэр. Бесплатные средства кроссплатформенной разработки (2010-01-11/2010-01-11)
Copyright © 2003-2023 by Sir Serge