Обновление в статьях
Изрядно обновил статью , поместил ссылку на неё в статьи. Если коротко: то в общем и целом настройка чуть упростилась и улучшилась. Но дёготь остался, куда без него.
Изрядно обновил статью , поместил ссылку на неё в статьи. Если коротко: то в общем и целом настройка чуть упростилась и улучшилась. Но дёготь остался, куда без него.
В преддверии похода по Восточному Саяну впервые приготовил топлёное масло. Оказалось несложно - главное подобрать хороший исходный продукт.
Вырвано из G+:
С сайта:
A curated list of awesome C/C++ frameworks, libraries, resources, and shiny things
Систематизированный список библиотек для решения различных задач на C++. Пока ограничен битбакетом и гитхабом, поэтому добавить некоторые полезные библиотеки за пределами этих площадок пока (?) возможности нет.
Список раньше хостился на GitHub, теперь обрёл второе рождение в виде сервиса.
Система рейтингов и меток должна помогать выбирать полезное. Как будет работать на самом деле - покажет время.
В подвале сайта смотреть подобные каталоги для других языков, в частности, Rust и Go.
На первомайские планировали сходить немного траверса по Партизанскому хребту с заходом на г.Синяя. Заход: по р.Икрянка от села Ястребовка. Выход: р.Правая Икрянка в село Ястребовка.
Идея поста родилась при употреблении чая во внутрь на южной кухне.
Недавно смотрел один доклад (точнее бегло просматривал) про Rust и в момент, когда начался рассказ про life-time, глаз зацепился за такой опасный пример из мира C++:
string get_url()
{
return "http://htrd.su";
}
string_view get_schema(string_view v)
{
// тут какие-то действия, я их опущу
auto result = v;
return result;
}
int main()
{
auto v = get_schema(get_url());
}
Что такое string_view - смотреть тут или тут. Если коротко - это невладеющая строка. Полезна для экономии на аллокациях, когда нужно работать с частями исходной строки.
В общем, из природы string_view
следует и проблемы в коде выше: get_url()
вернёт временный объект, который будет уничтожен в конце выражения, а следовательно, v
будет ссылаться на невалидный участок памяти.
У меня в голове родилось, сходу, вариант защиты от такого: так как string_view
не владеет строкой, то перемещение для строки сделать невозможно (да и семантически неверно), а перемещающий конструктор будет предпочтён для временного объекта. Следовательно если сделать перемещающий конструктор для string
у string_view
удалённым, то код выше сломается на этапе компиляции.
Пост для истории. Основные посылы, которые “не позволили” мне воспользоваться конвертером для ручки Platinum Balance можно почитать на penmania.ru.
Перезаправка картриджа не более грязная или долгая работа (наоборот, показалось, что выходит более чисто и быстро) чем заправка конвертера ручки. Но меня мучал вопрос хранения уже заправленных картриджей, ведь в этом случае проблема перезаправки становится ещё менее выраженной: при большей ёмкости и N-ном количестве картриджей шприц для заправки и бутылёк чернил можно хранить только дома и не носить с собой вообще.
Из того, что мне понравилось:
Кроме того, на ресурсе cppreference.com есть свой список библиотек под различные задачи (в дополнение к предыдущему посту), и, в частности, для графики.
ЗЫ по ссылке выше есть интересная библиотечка для пользовательского интерфейса (GUI):
nana, стоит пощупать. А так же для TUI:
cwidget.
ЗЗЫ прочие ссылки:
На RSDN промелькнуло, может ещё кому полезно будет:
Кто хочет дополнить - шлите мёрж-реквесты.
Прочие полезные ссылки, спасибо @sikmir:
Пока речь пойдёт про алиасы (alias) для man. Потом, может быть, что-то будет дополнено.
Часто возникает вопрос: “man чаво?”. Кроме того, интересные программистам документы, обычно, находятся в секциях 2 (системные вызовы), 3 (библиотечные вызовы) и 7 (стандарты, соглашения, обзоры). По назначению других секций можете спрашивать: man # intro
где #
- номер секции от 1 до 7.
В общем родилось три алиаса: для обращения и для поиска.
Для использование, код ниже поместить в ~/.bashrc
alias man-prog='man -s 2,3,7'
alias man-prog-search='man -s 2,3,7 -K'
alias man-prog-apropos='man -s 2,3,7 -k'
Первый - просто ограничивает область поиска и по man-prog printf
выведет не описание команды, а описание функции.
Второй - обеспечивает полнотекстовый поиск по страницам, третий - по индексу (apropos). В чём разница. Поясню на примере:
$ man-prog-apropos tcp
clnttcp_create (3) - library routines for remote procedure calls
clock_getcpuclockid (3) - obtain ID of a process CPU-time clock
getcpu (2) - determine CPU and NUMA node on which the calling thread is running
pthread_getcpuclockid (3) - retrieve ID of a thread's CPU time clock
QwtCPointerData (3) - (неизвестный объект)
sched_getcpu (3) - determine CPU on which the calling thread is running
svctcp_create (3) - library routines for remote procedure calls
tcp (7) - TCP protocol
zmq_tcp (7) - 0MQ unicast transport using TCP
Вроде всё хорошо. Дальше:
$ man-prog-apropos TCP_CORK
TCP_CORK: ничего подходящего не найдено.
Оппа… В гуголь лезть? А если так:
$ man-prog-search TCP_CORK
--Man-- след: sendfile(2) [ просм (ввод) | пропуск (Ctrl-D) | выход (Ctrl-C) ]
--Man-- след: sendfile64(2) [ просм (ввод) | пропуск (Ctrl-D) | выход (Ctrl-C) ]
--Man-- след: sendmsg(2) [ просм (ввод) | пропуск (Ctrl-D) | выход (Ctrl-C) ]
--Man-- след: sendto(2) [ просм (ввод) | пропуск (Ctrl-D) | выход (Ctrl-C) ]
--Man-- след: splice(2) [ просм (ввод) | пропуск (Ctrl-D) | выход (Ctrl-C) ]
--Man-- след: tcp(7) [ просм (ввод) | пропуск (Ctrl-D) | выход (Ctrl-C) ]
в man 7 tcp
мы найдём искомое описание.
Сначала немного информации из мира С.
При запуске приложения (речь идёт о POSIX) вместе с ним открывается 3 файловых дескритоптора:
В стандартной библиотеки Си используется FILE*
-based буфферизируемый доступ к файлам и терминалу. В stdio.h объявлены следующие глобальные символы, которые отражают стандартные потоки ввода вывода:
stdin
stdout
stderr
Соответственно их свободно можно использовать вместе с семейством функций fread()
/fprintf()
, обеспечивая буфферизированный доступ.
Сами файловые дескрипторы POSIX объявляет через макросы в unistd.h:
STDIN_FILENO
STDOUT_FILENO
STDERR_FILENO
Соответственно их свободно можно использовать со всем семейством функций read()
, write()
и, даже, select()
/epoll()
и fcntl()
(например, при помощи fcntl(O_NONBLOCK)
+select
+read
можно реализовать аналог [getch()](http://www.codenet.ru/progr/cpp/spr/175.php)
из старого доброго Borland C++). Доступ через эти функции не буфферизирован.
Доступ к одному потоку разными механизмами в одной программе лучше не осуществлять: буферизация это уровень библиотеки C и внутреннего устройства FILE. write()
или read()
ближе к системным вызовам и ничего про это знать не обязаны. Как результат можете получить перемешивание текста даже в однопоточном приложении. Это не отменяет того файла, что сам fwrite()
может, в конце концов, вызвать write()
.
На этом экскурс закончим и вернёмся в C++.
В C++ для работы с потоками служит библиотека [iostream](http://www.cplusplus.com/reference/istream/iostream/)
. Причём доступ к конкретному стриму может быть как буфферизируемым так и не буфферизируемым (зависит от потребностей).
Библиотека декларирует объекты, связанные со стандартными потоками:
std::cin
- стандартный вводstd::cout
- стандартный выводstd::cerr
- стандартный вывод ошибок иstd::clog
- для логированияПро std::cin
особо гооврить (пока?) не будем - он один, в своём роде. А вот про оставшиеся три стоит.
Итак, начнём с std::cout
и std::cerr
. В C++ они, помимо того, что связаны с разными дескрипторами, несколько отличаются поведением:
std::cout
- буферизируемыйstd::cerr
- не буферизируемыйТакое отличие явственно следует из семантики использования: ошибку нужно увидеть сразу без ожидания каких-то дополнительных действий со стороны программиста типа std::flush
или std::endl
(он, кстати, делает и flush, поэтому, для большей производительности строки в нормальном выводе стоит заканчивать ‘
n’, а не std::endl
).
Ок, а что за std::clog
? А это всего-лишь std::cerr
+ буферизация. И снова, семантика использования проста: диагностика может чуть и подождать, что бы не понижать производительность вывода, но смешиваться с нормальным выводом не есть хорошо, мы, ведь, можем использовать приложения в пайпе и, желательно, разделить диагностику и ошибки от обычного вывода.
Собственно, немного обобщая:
std::cout
- используется для обычного вывода результатов работы программы на экран, эти данные могут быть переданы дальше по пайпу для обработки.std::cerr
- вывод сообщений об ошибке в обработке, что бы не подмешивались в основной поток и не ломали логику работы других программ в пайпе. При этом сообщение выводим максимально скоро.std::clog
- используем для разного рода диагностических сообщений, но когда использование std::cerr
замедляет вывод из-за более частого дёргания системных вызовов, при этом, не подмешиваемся в основной поток и не мешаем работе других приложений в пайплайне.Хорошим тоном, так же, является вывод справки по программе в std::cout
, если вызвано с параметрами -h|--help
- тогда её удобно смотреть в, например, less без дополнительных телодвижений, а вот справку по опциям, в случае неправильной установки какого-то параметра (или пропуска обязательного), лучше выводить (тут особой разницы не вижу) в std::cerr
или std::clog
.
И, на последок, лекция по поводу тормозов iostream и вообще, а как оно там внутри устроено:
Недавно на ru.SO проскочил вопрос: как можно подключиться к SSM ( Source Specific Multicast) группе?
Нюанс в том, что для этого используется опция MCAST_JOIN_SOURCE_GROUP
для которой нет объекта-обёртки. Но, как оказалось, такой объект пишется самостоятельно на раз-два. Под катом я продублирую
свой ответ, как пример подхода реализации нужного функционала. Пример не самый идеологически правильный, но, как оказалось, рабочий. Автор сам предложил
свой вариант с захватом сырого хендла. Такой подход тоже имеет смысл в некоторых ситуациях((у меня случилось однажды так подружить сетевые абстракции Asio и libev, реализовав, тем самым, реактор на Asio :simple_smile:)).
23 февраля решили отпраздновать очередным снегоступингом.
По предложению Кирилла рассматривали варианты посещения южных отрогов Ливадийского хребта.
Маршрут изначально рассматривался как:
Фокино-г.Халаза-г.Горбуша-г.Лысый дед-Молёный мыс
но в результате был скорректирован до:
Душкино-падь Светланка-г.Круглая-г.Пидан-Лукьяновка.
Собралось три человека: я, Кирилл, Саня. В роли адового тропильщика в этот раз Кирилл.
Я подумал и решил, что функционала и стабильности достаточно для релиза версии 1.0.
Так что да будет так: https://github.com/h4tr3d/geocrop/releases/tag/v1.0
Если у вас на входе привязанный GeoTIFF, то проблем нет никаких, но если у вас просто растр (.png, .jpeg, .gif) и привязка для него, то есть нюансы. Вообще, GeoCrop умеет работать с любыми данными, с которыми умеет общаться GDAL. Но в в некоторых случаях не всё получается гладко, так, например, только сегодня он научился читать файл проекции для world-привязок (пара .prj+.pgw).
На просторах интернета можно встретить различные описания привязок, самые популярные:
GDAL не умеет только шифрованные OZFX, а так привязанная карта представляет собой пару .map+растр, где растр - это, обычно, .gif, .jpg или .png, реже - .bmp. При наличии такой привязки geocrop можно вызвать без дополнительных приготовлений: geocrop -f VRT -s 50k K-53-026-A.map K-53-026-A.vrt
Обратите внимание, что передаётся map файл, а не растр.
Т.к. сама привязка состоит из двух файлов (.prj+.pgw), то не так просто сказать, что и откуда читать. Согласно документации .pgw, .pngw или .wld файл((Описание формата: http://www.gdal.org/frmt_various.html#WLD)) подтягивается автоматически, если на входе карта в PNG (про другие форматы - ниже), а вот .prj файл нужно читать самому. Для этого в последней версии GeoCrop сделана небольшая эвристика:
-p srs_def
Т.е. при наличии привязки в виде world files GeoCrop так же можно вызвать без дополнительных приготовлений так: geocrop -f VRT -s 50k K-53-026-A.png K-53-026-A.vrt если файл проекции находится в K-53-026-A.prj или K-53-026-A.prf, или так: geocrop -f VRT -s 50k -p K-53-026-A.wkt K-53-026-A.png K-53-026-A.vrt
Обратите внимание, что в обоих случаях в качестве входного источника передаётся сам растр, а не его привязка.
Если у вас растры отличные от PNG:
Полный и актуальный список всегда можно посмотреть тут: http://www.gdal.org/formats_list.html
В данный момент GDAL не поддерживает данный формат, а значит не поддерживает и GeoCrop. Ищите способ как сконвертировать его во что-то удобочитаемое.
Вообще .gmw файлы достаточно простые для разбора, так что, возможно, появится у меня и их поддержка. Тем более, что для тех же карт GGC там сразу зашита информация об обрезке (только странно, что они сразу не сделали рамку прозрачной).
Теперь в
GeoCrop появился новый режим: генерация полигона для обрезки рамки в формате CSV+WKT. Вывод на stdout, так что можно сохранить в любой удобный файл из скрипта, после чего использовать как аргумент для -cutline
у gdalwarp в какой-то более сложной команде. Вызова gdalwarp при этом не происходит.
Активируется режим опцией -g
(от [g]enerate). Указывать выходной файл при этом не нужно - он будет проигнорирован.
Так же, теперь появилась возможность указывать файл с описанием проекции: -p srs_file
. Сама проекция должна быть в формате WKT или PROJ.4. Эта опция перезаписывает определение проекции в текущем файле. Полезна для преобразования файлов с привязками в виде world-файлов. Более того, если проекция в файле пустая, а опция не указана то произведётся попытка прочитать её автоматически из файла с таким же именем, но с расширением .prj или .prf (какой первый попадётся). Так что популярные карты ГГЦ с такими привязками теперь можно конвертировать так же просто, как и с привязками Ozi Explorer.
Чуть раньше реализована функциональность по передаче дополнительных параметров gdalwarp. Для этого нужно завершить опции приложения двойным минусом --
, опции после него будут переданы gdalwarp как есть без изменений:
geocrop -f VRT -s 200k K-53-07.map K-53-07.vrt – -overwrite
опция -overwrite
будет передана gdalwarp. Помимо этого, теперь можно переопределить и сам исполняемый файл gdalwarp - опция -w GDALWARP
.
Кроме того изменился формат опций, стало возможным указывать выходной формат (опция -f FMT
, как следствие, образовались такие возможности:
post/2016/02/11/bystro_i_nenavjazchivo_gotovim_kartu_dlja_otkrytija_v_qmapshack) или только обрезать рамку, не делая кроп (опция -n
).