LINUX.ORG.RU

Сообщения slovazap

 

Нужность/аналоги ncurses/slang

Захотел я написал что-то типа рогалика.

Поигрался с ncurses и libslang, написал пару тестовых приложений, ужаснулся интерфейсу этих библиотек и точно понял что использовать их я не хочу.

Вопрос: а нужны ли они? Чем я рискую, если буду просто выводить ANSI последовательности для перемещения курсора и установки цвета и собственно символы для рисования того что нужно? Плюс ioctl(TIOCGSIZE) и ловля SIGWINCH для контроля размера терминала, и плюс свой движок который умеет обновлять только изменившиеся части сцены.

slovazap
()

Выбор ноута (главным образом для разработки)

До сих пор обходился в поездках стареньким ASUS Eee PC с дебианом, но сейчас чувствую что нужна нормальная машина. Ноутом пользуюсь не часто, нужно в основном для:

  • немного покодить или посмотреть фильм на даче по вечерам или в поездках
  • для поездок на конференции (т.е. нужен выход на проектор)
  • смотреть HD видео с GoPro3

Сам я работаю под FreeBSD, так что хотелось бы чтобы ноут нормально работал под ней (wifi, приемлемое время работы, нормальная работа иксов), но особо на это не надёюсь - подойдёт и Linux. Скорее всего поставлю Gentoo, но советы по дистру тоже принимаются. Тут из предпочтений - похожесть на FreeBSD: source-based, ибо неизвестно как собранным бинарным пакетам не доверяю, хочу иметь исходники всего под рукой (как примеры кода, для возможности пересобрать что нужно с отладочными символами и для возможности починить чужой код), свежие версии софта, отсутствие разделения библиотек на собственно библиотеки и заголовочные файлы, возможность быстро написать отсутствиющий ebuild и получить нормальный пакет, ну и -march и откусывание ненужных зависимостей всегда плюс (первое на библиотеках которые я использую иногда даёт прирост в разы); здоровый консерватизм (т.е. безо всяких там systemd, логов на tmpfs и wayland). DE я не использую - в основном notion + zsh, так что много конпелять мне не придётся (хотя насколько я помню, gentoo пересобирает полсистемы при изменении любого флага? там не появилось опций как во FreeBSD - отдельных на каждый пакет?).

В общем, главные вопросы:

  • Наверное, для разработки и HD видео мне нужен ноут на Core i3/i5, а с ним и на gentoo можно будет нормально жить (разумеется, пакеты будут собираться при наличии нормального питания)?
  • Стоит ли гнаться за матовым экраном? Недавно сорвал изрядно потёртую матовую плёнку с N900 - теперь пользоваться невозможно, на глянцевом экране смотрю кино - вижу себя (и отпечатки пальцев). И это ещё в метро где ярких источников света нет.
  • Что там сейчас с выходами на проектор? Можно ли ожидать в обозримом будущем везде всё ещё будет доступно VGA, или он вытесняется? Чем, DVI или HDMI? Стоит брать ноут с 2 выходами или есть какие переходники?
  • Что с видео? В принципе, коровского встроенного мне хватит - OpenGL софт я пишу, но без серьёзных требований. С другой стороны, наверняка при просмотре фильмов через vdpau будет меньше жраться батарейка? Есть ли ноуты только со встроенным видео, или во всех будет видеокарта? Если второе, как сейчас с optimus'ом? Как вообще выглядит переключение между встроенным/дискретным видео, насколько оно прозрачно и настраиваемо? Есть ноуты с Intel HD Graphics - это встроенное в core, или что-то мощнее? Как оно вообще?
  • Нормальной раскладки клавиатуры не бывает? (с Enter на 2 строки)
  • Есть какие-нибудь замечания по брендам?

также:

  • Оптический привод не нужен
  • SD картовод нужен
  • Открыл для себя что есть ноуты с 3G. Думаю, не нужен.
  • Варианты с windows не рассматриваются - не хочу ни платить за него, ни иметь головную боль с возвращением денег.

В общем, наверное мне нужно выбрать что-то из:

http://www.fcenter.ru/products.shtml?eshop/act=p:a:0:35:a:a:a:1:a:1:25:r:1:1:...

Что посоветуете?

slovazap
()

Работа с множеством интерфейсов

Хочу я сделать такую штуку. Объясню на примере.

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

Как я это вижу:

Есть множество интерфейсов:

IApplyForce { virtual void ApplyForce(int nobj, vector force) = 0; }
IRotateObject { virtual void RotateObject(int nobj, float angle) = 0; }
ISetFriction { virtual void SetFriction(float amount) = 0; }

Движки реализуют его подмножества:

Engine1: public IApplyForce, public IRotateObject, public ISetFriction {}
Engine2: public IApplyForce, public IRotateObject {}
Engine3: public IApplyForce, public ISetFriction {}

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

// Допустим, пользователю не нужно трение вообще
SmartEnginePointer<IApplyForce, IRotateObject> engine = new Engine1;

// Так можно сделать, Engine2 реализует нужные интерфейсы
engine = new Engine2;

// Тут ошибка компиляции, ибо IRotateObject не реализован
engine = new Engine3;

Есть идеи как это реализовать?

 

slovazap
()

Дизассемблировать DOS'овский EXE'шник

Нужно сабж. Городить wine/виртуалку с виндой и ставить туда ida или другую проприетарщину не хочу, хочу нативное приложение. mingw32-objdump пробовал, не работает (File format not recognized). file говорит «MS-DOS executable, MZ for MS-DOS».

slovazap
()

lua, js - сравнение целых чисел учитывая что они хранятся как double

Известно, что как lua (по умолчанию) так и javascript хранят все числа как IEEE double. Известно также что результаты вычислений во floating point нельзя проверять на совпадаение, т.к. 0.1 + 0.2 != 0.3.

Вопрос - а как в этих языках реализуется целочисленная арифметика? Какие есть гарантии по поводу неё? Тест на js показывает, что (0.7 + 1.9 == 2.6) === false, но (7 + 19 == 26) === true, и даже (7.0 + 19.0 == 26.0), хотя 7 ровно также непредставимо в качестве конечной двоичной дроби как и 0.7. Ясно что оно не сравнивает числа с epsilon допуском, иначе в первом случае было бы true, значит или там хранится флаг целого числа (причём 7.0 тоже считается целым), или результат, достаточно близкий к целому (с достаточным числом нулей после запятой) считается целым. Где про это почитать чтобы не влететь в неожиданности с целыми числами вообще, а в особенности с большими целыми числами, где начнёт сказываться ограничение точности double?

slovazap
()

Сервис/тулза для учета проектов, работающих на сервере

Есть полудомашний сервак, который кроме меня пользуется ещё десятком человек в разных целях. Последнее время его несколько раз случайно роняли, и я подумал что пора уже навести порядок - описать кто там чем занимается и какие ресурсы использует, и в соответствии с потребностями выдать квоты, чтобы сломавшиеся скрипты не наплодили миллион процессов, скажем. Вопрос - что взять для учёта ресурсов? Если есть что-то специализированное, с удовольствием посмотрел бы, но сойдёт и wiki. В последнем случае желательно что-то совсем легковесное, желательно даже без необходимости поднимать БД.

В общем нужно всего навсего следущее: - табличка пользователи: ник-username-телефон-email-jabber - табличка проекты: название-хозяин-используемые ресурсы (по каким путям хранятся файлы, какие системные пакеты необходимы, какие сервисы поднятые на машине использует (http, почта, DNS), какие поддомены DNS использует, какие задания в кроне, как часто запускаются, как долго работают, сколько процессов плодяд, сколько памяти жрут и т.д.) проекты желательно группировать по разным признакам

slovazap
()

Научите настраивать шрифты

Проблема следующая: честно говоря, сколько себя помню русский и английский текст у меня показывались то-ли разными шрифтами, то-ли разными настройками. Вроде привык и не обращал внимания. Но сегодня прилетело обновление liberation-fonts-ttf с 1.07.0 до 2.00.1, и все стало плохо. Научите, пожалуйста, настраивать шрифты.

Вот так это выглядит (вводил в firefox в одну textarea, т.е. настройки шрифта как-бы одни), сверху - до обновления liberation, снизу - после:

http://fastpic.ru/view/47/2012/1120/b6237a0cfe673db546806e9ae9104ab3.png.html

- почему английский и русский по-разному антиалиасятся? разные ли это шрифты?

- что за мазня вылезла после обновления?

Как сделать чтобы всё было либо как сверху-слева, либо как сверху-справа (не уверен пока что мне больше по душе).

Заранее спасибо.

 

slovazap
()

mmap памяти в память

Можно ли сделать mmap не файла, а куска памяти?

Задача такая: у меня есть массив данных double[] и алгоритм, который в процессе работы этот массив меняет. При этом алгоритм должен вызываться много раз на первоначальных данных, т.е. напрямую менять их нельзя. Особенность такова, что в хорошем случае (таких большинство) он изменит лишь малую часть массива, но в плохом изменит его весь. В результате получается, что если тупо делать копию данных для каждого вызова алгоритма, большую часть времени программа копирует данные (фактически зря, потому что менять надо будет мало). А если не копировать данные, а делать std::map/unordered_map только с изменившимися значениями, всё начинает работать медленно из-за плохих вариантов, и профайлер показывает что время тратится в кишках map и аллокаторах.

В общем, нужно что-то типа гибридного решения: без мапы, но и чтобы всё не копировать. Показалось логичным использовать возможности виртуальной памяти и сделать что-то типа copy on write, чтобы при изменении страницы копировалась только она одна. Как такое можно сделать без костылей типа записи исходного массива в файл?

slovazap
()

Узнать почему OpenGL работает в software

Есть некое 3D приложение, и оно, несмотря на кажущуюся простоту отрисовываемой сцены, работает непростительно медленно на весьма мощной видюхе. Есть подозрение, что причиной тому использование какой-то одной несовместимой фичи, из-за чего OpenGL переключается в software. Вопрос: как узнать из-за чего именно это происходит?

Была идея смотреть на glXIsDirect, но он всегда возвращает единицу. В реализацию OpenGL тоже особо не встроиться, она от блоба нвидии.

slovazap
()

Каноничное название для поддиректории с внешними библиотеками

Есть у меня проект, и с ним бандлятся несколько библиотек (тоже моих, но допустим что могут быть и чужие). Логично, что они живут в своей поддиректории. Вопрос - какое самое каноничное название для этой директории? 3d-party/, 3rd-party/, contrib/, другое?

slovazap
()

[ffmpeg] перемотка по кадрам в обе стороны

Собственно, задача - сабж. Есть видео в h264 (потенциально в чем угодно), нужно уметь мотать его по одному кадру в обе стороны, а также перескакивать точно на нужный номер кадра. Как я понял, в общем случае это невозможно, но для начала возьмем частный, когда есть индекс. av_seek_frame может seek'ать до кейфреймов, от которых можно домотать вперед до нужного кадра, и тут два вопроса.

Во-первых, как узнать номер кадра после перемотки до кейфрейма? DTS/PTS ненадежны - у меня есть видео где PTS нет, а DTS начинается с 2. Разве что сразу после открытия файла читать первый кадр и сохранять его DTS.

Во-вторых, кейфреймы могут располагаться достаточно редко (у меня раз в 60 кадров), т.е. получается что при сике на 1 фрейм назад с кейфрейма придется делать av_seek_frame до предедущего, декодить 60 фреймов и, видимо, ещё и сохранять их в памяти, чтобы не декодить 59 штук при следующем сике. Есть какой-то более эффективный способ?

Есть один нюанс - видео у меня в любом случае предобрабатывается с последовательным чтением кадров, поэтому есть вариант построить свой индекс с произвольной частотой кейфреймов и нумерацией кадров, с привязкой к смещению пакетов в видео файле. Как это лучше сделать? Получится ли просто считать кейфреймами все I-фреймы и просто мотать до них av_seek_frame'ом по смещению, или всё сложнее (что-то говорит мне что нужно два I-фрейма чтобы работали B-фреймы)?

PS. ffmpeg_fas смотрел, он с моим видео просто не работает.

 

slovazap
()

Unicode в С++

Понадобился мне тут сабж, и после дня ковыряний появился вопрос - это вообще возможно? Ситуация такая: CLI приложение, у него есть файл данных жёстко в UTF-8, также оно должно читать/писать пользовательские данные (думается, в его локали), а внутри работать со строками посимвольно + tolower/toupper + какая-никакая сортировка.

Как я понял, «C++» way - использовать эти locale и facets, только нигде по ним нет нормальной документации. Во всех примерах конвертят (через facet шототам .wider) ASCII из char* в wchar_t* - замечательно но только если в char* UTF8 то конвертит оно по байтам а не по символам. Это во-первых. Во-вторых, оно зависит от этого долбаного setlocale, а мне нахрен не упёрлось чтобы конвертация между utf8 и широким форматом как-то зависела от локали. C++'ного преобразования регистра нет, конвертим строки через towlower/towupper, что тоже с какого-то хрена зависит от локали. Сишный way с mbstowcs завист от локали аналогично. Кое-где советуют писать свою utf8 локаль или брать из буста с хитрыми хаками по переопределению namespace'ов.

Порыскал по интернету, нашёл замечательную библиотечку http://slonik-v-domene.livejournal.com/17731.html?thread=93507 как я понял utf8<->wide + lower/upper, безо всяких идиотских локалей. Там, правда, уродский сишный интерфейс с кучей аллокаций, но это не проблема переписать. Также для широких символов там используется не wchar_t, а unsigned int, а это уже не попихаешь в в wcout.

Ещё есть ICU (с совершенно ублюдской документацией) и, в конце концов iconv (хотя я бы предпочёл отказаться от внешних библиотек вообще).

Ещё есть новые литералы и char16_t/char32_t в C++11.

Итого - всего много, но ничего нормально не работает. Как быть?

Предполагаю что правильнее всего было бы разобраться с C++ локалями/фасетами и написать свои классы для utf8 и возможно utf32 с возможностью конвертации между ними, а для последнего case и сортировку. Однако нужна вменяемая документация на то как оно работает и вообще что эти фасеты значат. Другой вариант - сделать basic_string<int32_t> и написать для него функции конвертации в/из string (с utf8) и tolower/toupper и забыть про этот ад. Общение с пользователем оставить только в utf8.

slovazap
()

Альтернатива flex

Решил наконец изучить flex & bison. Изучил, понравилось. Начал прикручивать парсер к C++ проекту, полез глубже копаться (начал пока с голого лексера), и охренел.

Во-первых, код ни разу не exception-safe. Как вам это (сгенерённый код):

YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size )
{
        YY_BUFFER_STATE b;
    
        b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
        if ( ! b )
                YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );

        b->yy_buf_size = size;

        /* yy_ch_buf has to be 2 characters longer than the size given because
         * we need to put in 2 end-of-buffer characters.
         */
        b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2  );
        if ( ! b->yy_ch_buf )
                YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );

        b->yy_is_our_buffer = 1;

        yy_init_buffer( b, file );

        return b;
}

Если лень читать - при фейле alloc вызывается YY_FATAL_ERROR. Что прикажете мне в ней делать? Если просто вывести ошибку и сделать вид что ничего не случилос (ну или установить флаг и выкинуть результаты кривого парсинга), то после фейла первого аллока при обращении к b->yy_ch_buf будет SEGV. А если кинуть исключение, при фейле второго alloc'а память, выделенная в первом весело утекает. Получается, что делать остаётся только abort, весело.

Во-вторых, C++'ный лексер наследуется от помоечного класса yyFlexParser, набитого кучей ненужной гадости типа работы с потоками, которые мне нахрен не сделись, вместо того чтобы наследоваться от виртуального интерфейса и дать мне возможность самому определить как работать с вводом/выводом, как выделять память и как обрабатывать ошибки. На самом деле, я пришёл к выводу что из C++ удобнее будет использовать сишный reentrant лексер, а не плюсовый, но невозможность обработки ошибок остаётся, и мусор там свой есть.

В bison глубоко не копал, но сдаётся мне там будут свои проблемы с памятью и исключениями.

В общем, хочется инструмента из этого века - удобного, гибкого и безопасного. В идеале - сочетающего лексер, парсер и кнопку «сделать заебись», но хотя бы по минимуму - нормальный лексер, который не генерит говнокод, позволяет управлять буферами как я хочу и не суёт в нос работу с FILE* или ++'ными потоками. В качестве лексера на ум приходит только ragel, но может есть лучшее и/или комплексное решение?

slovazap
()

Аналог FF аддона permit cookies

Пользуюсь до сих пор Firefox 3.6.x из-за аддона permit cookies, который не позволяет сайтам устанавливать куки, пока я не разрешу. Хочется перейти на FF поновее, но permit cookies не поддерживает новые версии FF. Внимание, вопрос: есть ли аналог аддону (желательно пофичастее), или стоит попробовать похачить его на предмет версии в надежде что он заработает под новым FF либо разобраться и напрямую портировать под новую версию?

Ещё интересен аналог xpather - аддон, показывающий в html документе xpath для выбранного элемента.

slovazap
()

Правильный MVC для игры

Есть хитрая настольная игра, хочется сделать её компьютерную реализацию, и хочется сделать её по принцыпам, схожим с MVC - есть модель, описывающая правила и ход игры, есть контроллер, передающий дествия игрока, и есть вид - собственно отображение происходящего в игре. Нужно это чтобы легко можно было менять контроллеры (локальный игрок/удалённый игрок/AI) и виды (GUI/Curses/Web UI, заодно контролировать из модели кому какие данные разрешено видеть). На деле получилось как-то не особо по канонам MVC, в связи с чем следующие непонятки:

1) Взаимодействие модели и контроллера. У игры куча фаз хода игрока, которые могут прерываться другими игроками, и ОЧЕНЬ хочется реализовать это в виде императивного кода, дёргая контроллер когда нужно действие игрока. Т.е.

void Game::Turn() {
  DoFoo();
  m_Controller->AskForAction(SELECT_UNIT);
  DoBar();
  m_Controller->AskForAction(CAST_SPELL);
  DoBaz();
  m_Controller->AskForAction(BUY_STUFF);
  ...
}

допустим, это будет работать с Curses, где в контроллере можно просто ждать нажатия клавиши. Но как быть, например, с GUI, где есть внешний цикл обработки событий? Придётся либо запустить копию цикла в контроллере, что, как мне кажется, криво и скорее всего возможно не во всех тулкитах, либо GUI банально не будет отрисовываться, пока пользователь не нажмёт нужную кнопку. Можно сделать отдельный поток, но это выглядит как костыль. Единственная альтернатива что мне видится - выходить из Turn когда нужно действие и его перезапуск когда действие получено (что-то типа FSM):

RequiredPlayerAction Game::Turn() {
  switch (m_TurnPhase) {
  case 0:
    DoFoo();
    m_Phase = 1;
    return SELECT_UNIT;
  case 1:
    DoBar();
    m_Phase = 2;
    return CAST_SPELL;
  case 2:
    DoBaz();
    m_Phase = 3;
    return BUY_STUFF;
    ...
  }
}

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

Как бы вы решили задачу, может я упустил какой-нибудь вариант?

2) Взаимодействие модели и вида: push или pull? Вроде в классическом MVC вид просит у модели данные и отображает их. Мне же более удобным видится вариант когда модель при изменении данных пинает вид. Второй вариант выгдятит гораздо лучше потому что взаимодействие происходит через жёстко определённый интерфейс вида, что обеспечивает хорошую абстракцию, тогда как в первом случае придётся либо давать виду const-доступ к кишкам модели, либо гененировать структуру данных, представляющую состояние игры (что по сути просто копия тех же кишок), а структура этих кишок может меняться в процессе разработки модели.

Ну тут вроде всё понятно, но на всяких случай спрошу - push модель это в целом нормально?

slovazap
()

Приоритеты потоков

Диспозиция такая: есть два потока, один рисует данные opengl'ем, второй в фоне грузит куски данных. Реализована, соответственно, очередь запросов, защищённая мутексом:

// Главный поток
{
  while (1) {
    pthread_mutex_lock(mutex);
    ...
    отрисовка_данных(dataset);
    ...
    queue.push_back(request);
    ...
    pthread_mutex_unlock(mutex);  /* 1 */
  }
}

// Рабочий поток:
{
  pthread_mutex_lock(mutex);
  while (!die_flag) {
    while (queue.empty())
      pthread_cond_wait(condvar, mutex);
    request = queue.pop_front();
    pthread_mutex_unlock(mutex);

    data = долгая_обработка_куска_данных(request);

    pthread_mutex_lock(mutex);
    dataset.push_back(data);
  }
  pthread_mutex_unlock(mutex);
}

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

На деле же происходит следующая неприятая вещь: первый поток после рендеринга и добавления нескольких запросов в очередь вызывает pthread_mutex_unlock (/* 1 */) и не возвращается из неё 0.1 секунды, за которые второй поток и ухитряется обработать аж десяток кусков данных, соответственно, отображение в главном потоке заметно лагает. Насколько я понимаю, получается так потому что у первого потока, успевшего за время рендеринга пожрать циклов CPU, понижается приоритет, а т.к. второй поток это время спал, он вытесняет первый пока не догонит его по использованию CPU. Вставка sched_yield во второй поток помогает, но сейчас используется два потока, и лаги, хоть и менее заметны, всё ещё присутствуют. Как я понимаю, несколько рабочих потоков будут просто переключаются друг на друга, но не на главный.

Собственно вопрос: как избавиться от лагов? Я так понимаю, приоритеты потокам выставлять не очень хорошо потому что условиях нехватки CPU (т.е. 1 ядро занятое на 100%) поток с меньшим приоритетом будет голодать, а значит данные грузиться не будут. В идеале нужно чтобы главный поток не вытеснялся более чем на 0.01 сек, но при этом чтобы CPU с другими потоками получал поровну.

slovazap
()

C++ итераторы

Где-то документировано что инкремент итератора, указывающего на end() даёт begin(), а декремент - последний элемент? Или это вообще не гарантируется?

slovazap
()

Внеэкранный OpenGL

Хочется рисовать сцены OpenGL'ем на GPU, но не хочется создавать никаких окон. В идеале вообще без X, но на это я мало надеюсь, так что пойдет и с иксами - как можно создать GL контекст, не привязанный ни к какому окну?

slovazap
()

Обработка ошибок в библиотеке на C

Есть библиотека на plain C, которая работает с неким форматом файлов. Интерфейс простой:

typedef struct mylib {
  int mylib_errno;
  ...
} *mylib_t;

mylib_t lib = mylib_open("filename", ...);
somecount = mylib_getsomecount(lib, ...);
if (somecount < 0)
  errx(1, "cannot get some count: %s\n", mylib_strerror(mylib_getlasterror(lib)));

mylib_close(lib);

Т.е. в struct mylib хранится errno в котором могут быть как положительные значения (от системных вызовов и функций из libc) так и отрицательные от самой библиотеки.

Это отлично работает, но только когда в mylib_open ничего сложного не делается (тогда если возвращается NULL, это однозначно malloc вернул ENOMEM) и когда в качестве someval можно передать невозможное значение (ну это не особо проблема, потому что если нельзя, то можно передавать через указатель на манер stat(2)). Но вот нужно в mylib_open сделать что-то нетривиальное, и потом узнать что случилось. Вопрос: как лучше построить интерфейс в общем случае?

Вариант 1:

typedef int mylib_code_t;

mylib_code_t mylib_open(mylib_t *);
mylib_code_t mylib_getsomeval(mylib_t, int *)

Т.е. выходные данные всегда передавать через указатели, а возвращать всегда код ошибки (или MYLIB_OK). Это не нравится по той причине, что так пользователю вероятнее забыть что-то освободить, т.е. вызвать mylib_open(&lib) при уже открытом lib уже открыт. Все-таки с lib = mylib_open() это легче заметить. Далее, нельзя написать в одну строку struct mylib *lib = mylib_open() и общее несогласование интерфейса с обычными библиотечными функциями, которые возвращают данные а не коды.

Вариант 2:

Хранить свой глобальный errno. Описанных выше проблем нет, но имеем проблемы с многопоточными программами. С другой стороны, если есть портабельный способ так объявить mylib_errno, чтобы при сборке с потоками он был в TLS, а без потоков просто глобальным, ИМХО это было бы самое оно.

Вариант 3:

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

Идеи? Особенно интересует второй вариант. Есть мысли про установку обработчика ошибки + setjmp, но а коде который это использует невозможно разбираться, да и jmpbuf надо передавать опять таки. Т.е. это ухудшенный вариант 1.

slovazap
()

Алгоритм Хаффмана для последовательностей/больших алфавитов

Есть поток 32битных целых, надо его максимально эффективно сжать. Значения распределены неравномерно, скажем так примерно половина влезет в 16 бит, но на деле распределение еще сложнее - хочется построить максимально эффективный код. Нужно что-то типа алгоритма Хаффмана, но напрямую (с алфавитом из 2^32 букв) его не применить. Есть идея отталкиваться от длины последовательности, т.е. разбить значения на 32 класса по числу значащих битов, и для каждого Хоффманом вывести префикс. Но как учитывать в алгоритме длину, просто умножать на частоту? Может есть другие варианты - думаю было бы эффективнее разбить числа на большее число классов.

Ссылки/хинты/идеи?

slovazap
()

RSS подписка на новые темы