Добро пожаловать!

Я Дож, программирование — моё хобби. По мере того, как я осваиваю что-то новое, стараюсь об этом написать пост.
На текущий момент в блоге затронуты следующие темы: vim, free pascal, lisp, forth, m4
Занимаюсь разработкой своего языка под названием DEmbro, подбробней: wiki и svn
Для постов, не связанных с программированием, у меня есть отдельное жж.

февраля 12, 2010

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

:%s/doj/visualdoj/g

Заменяет все вхождения doj в файле на visualdoj. Если убрать g на конце, то действие в каждой строке будет сделано не более одного раза. Удобно при рефакторинге.
:g/\cdoj/nu

Выведет на экран все строки, содержащие doj. Если убрать \c перед doj, то получим поиск с учетом регистра.
:v/doj/d

Удалит все строки файла, кроме тех, которые содержат doj. Удобно если у вас есть лог-файл, из которого нужно выделить какую-то определенную инфу.

Помощь:

:help :s
:help pattern
:help :g


Читать дальше......

Я немного подзабил

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


Читать дальше......

октября 27, 2009

Один из способов создания алиасов в windows

Пусть нам нужно при наборе какой-то команды, например do, перенаправлять вызов в какую-то другую программу. Например, в mysuperutil.exe.

Один из способов это сделать - воспользоваться реестром:
1) открываем реестр (командой regedit)
2) идем в HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths
3) создаем новый раздел с именем do.exe и у переменной по умолчанию устанавливаем значением C:\myutils\mysuperutil.exe
4) закрываем реестр

Так же это отличный способ сократить путь к какой-то очередной утилите, когда не хочется засорять переменную %PATH%.


Читать дальше......

июля 15, 2009

Получаем стек в реальном времени

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

function BackTraceStrFunc(Addr: Pointer): ShortString;
Возвращает по адресу функции информацию о ней. В простейшем случае это будет просто адрес, а если скомпилировать программу с ключом -gl, то еще название этой функции и название файла, в котором она объявлена. В тот момент, когда программа падает и паскаль выводит стек вызовов - используется именно эта функция. Что забавно, это не функция, а переменная функционального типа, поэтому ее можно переопределить (BackTraceStrFunc := @MyBackTraceStrFunc;). Помимо адреса функции в нее можно передать информацию о вызове (см. get_caller_addr) и тогда будет выдан номер строки в исходнике, в которой был вызов.

function get_frame: pointer;
Возвращает указатель на фрейм вызова текущей функции. Сама по себе малополезна.

function get_caller_addr(framebp: pointer): pointer;
Возвращает указатель на место с информацией о том, откуда был вызван фрейм framebp. С помощью этого указателя уже можно получить при помощи BackTraceStrFunc информацию о вызывающей функции.

function get_caller_frame(framebp: pointer): pointer;
Возвращает фрейм, из которого был вызван фрейм framebp.

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

procedure PrintStack;
  var
    Frame: Pointer;
begin
  Frame := get_frame;
  while Frame <> nil do begin
    Writeln(BackTraceStrFunc(get_caller_addr(Frame)));
    Frame := get_caller_frame(Frame);
  end;
end;


Наслаждайтесь!


Читать дальше......

июня 06, 2009

Автоматическое автодополнение

В виме по умолчанию для автодополнения нужно нажимать ^N (т.е. Ctrl+N). Иногда, правда, хочется, чтобы редактор делал это автоматически по мере набора слова. Специально для этого есть плагин word_complete, который выполняет ремап в interst mode (т.е. делает imap) для каждой буквы, добавляя автодополнение.

Единственное неудобство скрипта - он использует стандартный вимовский буфер обмена.


Читать дальше......

мая 27, 2009

Проблема с property record'ом

Имеем код


type
TVec2f = packed record
  X, Y: Single;
end;

TClass = class
private
  FVec: TVec2f;
  procedure SetVec(V: TVec2f);
public
  property Vec: TVec2f read FVec write SetVec;
end;
  
procedure TClass.SetVec(V: TVec2f);
begin
  FVec := V;
  Writeln(V.X, ' ', V.Y);
end;

var
  Obj: TClass;
  V: TVec2f;
begin
  Obj := TClass.Create;
  V.X := 100;
  V.Y := 1000;
  Obj.Vec := V;
  Obj.Vec.Y := 666;
  Writeln('Last value: ', Obj.Vec.Y);
end.


Код прекрасно компилируется. Вся соль в предпоследней строке Obj.Vec.Y := 666. Возникает несколько вопросов
1) Будет ли вызван Writeln при выполнении этой строки?
2) Что будет напечатано в самом конце?

Ответы

1) Нет
2) "Last value: 6.660000000E+02"

Из-за этого совершенно неочевидного поведения я просидел в поисках ошибки в одной своей программе около часа.

Далее, если в этом же коде убрать "read FVec" и "Writeln('Last value: ', Obj.Vec.Y);", то компилятор будет ругаться на строку "Obj.Vec.Y := 666;".

От нас что-то скрывают! :)

Видимо, теперь record ведет себя как класс. В предыдущих версиях фпц такой код вообще не компилировался.


Читать дальше......

FPC 2.2.4

Полтора месяца прошло с появления FPC 2.2.4. С паскалем я, к сожалению, все это время дела не имел (использовал CodeGear Delphi 2009), а вот сегодня наконец пришлось.

Полный лог изменений в FPC 2.2.4.

Самое значимое - это полноценная поддержка generic'ов. А этого я ждал долго :) Теоретически, они были и раньше, но по факту при попытке специализации какого-то дженерика вываливалась ошибка "202 runtime error".

В скором времени перепишу паскалевский синтаксис в виме, чтобы слова generic и specialize подсвечивались.

Код с тестовым примером:


generic TList<TItem> = class(TObject)
var private
  FItems: Array Of TItem;
public
  procedure SetLength(Len: Integer); inline;
  function High: Integer; inline;
  function Length: Integer; inline;
  procedure Add(Item: TItem);
  procedure Del(Item: TItem; All: Boolean = True);
  function Find(Item: TItem): Integer;
  function GetItem(Index: Integer): TItem; inline;
  procedure SetItem(Index: Integer; Item: TItem); inline;
  property Items[Index: Integer]: TItem read GetItem write SetItem; default;
end;
TListOfInteger = specialize TList<Integer>;
TListOfString = specialize TList<String>;



Читать дальше......

Постоянные читатели

Обо мне

Моя фотография
Мой e-mail: vitek_03(at)mail(dot)ru