← All posts tagged code

borman

Дано: библиотека, умеющая читать некоторый структурированный формат. Парсит входной поток и отдает его в виде последовательности логических "событий". Интерфейс на C, интересно обернуть его для хаскеля. В связи с этим есть вопросы.

В целом оригинальный интерфейс выглядит как-то так:
stream = xxx_stream_from_fd(0);
// stream' = xxx_stream_from_string(data, length);
reader = xxx_reader_new(stream);
while ((event_type = xxx_reader_get_next_event(reader)) != XXX_EVENT_END_STREAM) {
    switch (event_type) { ... value = xxx_reader_get_???(reader); }
}
xxx_reader_delete(reader);
xxx_stream_delete(reader);

Понятно, что в х-е это должно быть какой-то монадой. 
1. Обязательно ли для случая с from_string чтобы всё происходило в IO? Этого хотелось бы избежать. Как в таком случае должен выглядеть тип, общий для обоих вариантов входных потоков?
2. xxx_reader_get_string возвращает указатель на кусок буфера внутри парсера (для zero copy). Указатель инвалидируется следующим вызовом get_next_event. Возможно ли безопасно описать такой контракт в типах?

borman

Попробовал потыкать палочкой rust. Пока что основной баттхерт от borrow checker'а.
Хотел написать парсер одного json-подобного формата. На нижнем уровне у него lexer:

struct Lexer<'a, T> {
    stream: &'a mut T,
    buf: Vec<u8>,
}

impl<'a, T: Buffer> Lexer<'a, T> {
    fn new(stream: &'a mut T) -> ...

    fn read_token(&mut self) -> IoResult<Token<'a>> { ... }

    ...
}

При этом Token - штука, которая может содержать слайс от buf.

В итоге при попытке это использовать, бьют канделябром по рукам:

let mut lexer = Lexer::new(stream);
loop {
    let token = lexer.read_token(); // А вот хуй! Говорят, что &mut self конфликтует с lexer.
}

Пытаюсь теперь понять, как от этой упячки избавиться. Пока приходит в голову только убрать из Lexer ссылку на stream (вроде тогда времена жизни выравниваются, но вылезает ад с передачей его в каждый из методов).

borman

/Совершенно случайно/ обнаружил занятное.

Допустим, кто-то опечатался, и поэтому у нас есть функция

bool test() {
  return test();
}


При компиляции, GCC выдает логичное:

test():
.L2:
 jmp .L2
 

Но Clang (3.4.0, -O2) удивляет, особенно если обнаружить это после запуска:

test():                               # @test()
 xorl %eax, %eax
 ret

Вот так вот.

borman

Пост памяти навечно покинувшего нас @tag:

[2014-02-15 16:38] INFO: Juick: https://api.juick.com/messages{'user_id': 4254}
[2014-02-15 16:38] DEBUG: Juick: -> 200 OK
{
  "body": "сферическая лайка в вакууме ( вынесено из#301291/6 )", 
  "tags": [
    "juick", 
    "like"
  ], 
  "timestamp": "2009-10-04 08:10:38", 
  "mid": 301685, 
  "user": {
    "uname": "tag", 
    "uid": 4254
  }, 
  "photo": {
    "small": "https://i.juick.com/photos-512/301685.jpg", 
    "medium": "https://i.juick.com/photos-1024/301685.jpg", 
    "thumbnail": "https://i.juick.com/ps/301685.jpg"
  }
}

Пользуясь случаем, передаю привет чувакам из #2658164, зарегавшим юзера @pm:

[2014-02-02 00:12:51] pm> Сообщение, которое нельзя прочитать из веб-интерфейса
[2014-02-02 00:16:09] 1      Alyona> Кококо
[2014-02-02 00:16:38] 2 -> 1 pm> @Alyona Не угадала.
[2014-02-02 00:17:14] 3 -> 2 Alyona> @pm А что мы тут угадываем?
[2014-02-02 00:17:31] 4 -> 3 pm> @Alyona Кто - вы?
[2014-02-02 00:18:38] 5 -> 4 pm> @pm Надеюсь, меня угнч не зобанит за этот аккаунт
[2014-02-02 00:19:16] 6 -> 5 snakehoney> @pm и меня
[2014-02-02 01:18:10] 7      stjn> @pm, вы прекрасны, спасибо.

borman

Тонкие обертки над сишным кодом иногда такие тонкие...

>>> import pygit2
>>> repo = pygit2.Repository('/tmp/repo')
>>> tree = repo[repo.head.oid].tree
>>> [item.name for item in tree]
['.gitignore', '__init__.py', ...]
>>> tb = pygit2.TreeBuilder(tree)
>>> tb.insert('foo', repo.create_blob('badabada'), pygit2.GIT_FILEMODE_BLOB)
python: /build/buildd/libgit2-0.18.0/src/tree.c:653: git_treebuilder_insert: Проверочное утверждение «bld && id && filename» не выполнено.
[1]    22227 abort (core dumped)

borman

А вот такой вопрос к емаксерам: можно ли в diary присобачить к группе повторяющихся событий ограничение типа "отрезок времени"? То есть например я забил туда свое расписание, получилось в таком просто прекрасном формате:

&Tuesday
	10:30-12:05 510  Прикладная алгебра
	12:15-13:50 510  Прикладная алгебра
	14:35-16:10 П-13 Параллельная обработка данных
	16:20-17:55 П-13 Социология

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

borman

А вот интересно стало, как у "взрослых" принято делать обходы каких-нибудь древесных структур, например? Детишки, я знаю, для этого пишут рекурсию, что чревато срывом стека в реальной жизни. Я вот решал подобную задачу и сделал подобное:

void SomeTreeFormat::writeTree(ostream &out, TreeNode *tree)
{  
    out << tree->size() << endl;

    class SomeTreeFormatDelegate: public TreeNode::Delegate
    {
        size_t m_indent;
        ostream &m_out;
    public:
        SomeTreeFormatDelegate(ostream &out): m_indent(0), m_out(out) {}
        void onEnterNode(TreeNode *node, TreeNode *)
        {
            m_out << Indent(m_indent) << node->name() << " " << node->id() << endl;
            m_indent += 4;
        }
        void onExitNode(TreeNode *, TreeNode *)
        {
            m_indent -= 4;
        }
    } delegate(out);
    tree->traverse(&delegate);
}

Что думают товаг'ищи специалисты? Вроде как, в С++11 есть замыкания и можно так не ебаться и сделать лямбды, хотя я не изучал этот вопрос, но интересует, как делают во всем привычном С++03.

borman

Полез в API к clang, и что я там вижу?:

void 	SetExternalSource (ExternalHeaderFileInfoSource *ES)
 	Set the external source of header information. 
void 	setTarget (const TargetInfo &Target)
 	Set the target information for the header search, if not already known. 

ШТОЭТАБЛЯДЬ за стиль кодирование такой? Картинка в тему: 
http://www.examiner.com/images/blog/wysiwyg/image/jackie(8).jpg

borman

Читаю код проги, написанной одногруппников, которой завтра надо будет пользоваться. Наблюдение первое: легкий шок от того, насколько отличный от моего подход к написанию может применяться на практике. Наблюдение второе: прелестное своей элегантностью решение
QFile old("matrix.txt");
if (old.exists())
{
    if (!old.remove())
    {
        //QMessageBox::critical(this, "Error", "Can't remove old matrix.txt");
        //return;
        system("DEL /F matrix.txt");
    }
}

borman

Жуйк, кто-нибудь связывался с OpenIndiana? А то такие дела:

borman@indiana:/tmp$ cat test.cpp
#include <cstdio>

int main()
{
  printf("Hello World!\n");
  return 0;
}

borman@indiana:/tmp$ g++ test.cpp
In file included from test.cpp:1:0:
/usr/gcc/4.6/lib/gcc/i386-pc-solaris2.11/4.6.1/../../../../include/c++/4.6.1/cstdio:44:19: fatal error: stdio.h: No such file or directory
compilation terminated.

borman

Мне в текущем протоколе XMPP-API не нравится то, что оповещения об успешно выполненных отписках не привязываются к треду, от которого отписался. Пример:

>>>> borman99@jabber.ru/codeee/Vacuum IM 12:07:48 +0 >>>>
  <message from="borman99@jabber.ru/codeee/Vacuum IM" type="chat" to="juick@juick.com/Juick">
    <body>U #1111111</body>
    <juick xmlns="http://juick.com/message"/>
  </message>

<<<< borman99@jabber.ru/codeee/Vacuum IM 12:07:49 +314 <<<<
  <message from="juick@juick.com/Juick" type="chat" to="borman99@jabber.ru/codeee/Vacuum IM">
    <body>Unsubscribed!</body>
  </message>

Наверное, самый разумный вариант --- просто их перехватывать и игнорировать, но все же, удобно было бы иметь возможность правильной их маршрутизации.