256
Ну чтос, с праздничком!
Ну чтос, с праздничком!
В продолжении темы, поднятой мною тут: 906984 , таки решил озадачится, результатом озадачивания стало два скрипта.
Для того, что бы к работал поиск в “Указателе”, нужно указывать ключевые слова, в данный момент, в качестве оных, используется имя самой страницы. Полнотекстовый поиск будет доступен в соответствуем месте в Qt Assistant после окончания генерации индекса. В “Содержании” добавится новый пункт “Unix man pages”.
Вот так вот примерно это дело выглядит:
Сразу вопрос: подскажите инструмент для генерации ключевых слов для документа, интересует, на данный момент, только английский язык.
Бонусом нам это добавляет контекстную справку по всем функциям glibc и установленных библиотек (для которых есть man-page) в Qt Creator.
Сгенерированный мною файл справки можно взять тут: http://hatred.homelinux.net/~hatred/unixman.qch.gz
UPD:
буквально сегодня в списке рассылки Qt Creator проскользнула статья:
Linux Man Pages integration with Qt Creator со схожим механизмом получения справочного файла. Отличие в том, что он брал готовые man-страницы в html с
http://www.kernel.org/doc/man-pages/online_pages.html
UPD2:
Там же в рассылке всплыла ссылка на галерею документации для Qt Creator:
https://wiki.qt.io/Qt_Creator_Documentation_Gallery (или поиском по “Qt_Creator_Documentation_Gallery”, так как они уже несколько раз домены тосовали).
В текущем состоянии не густо, но есть C++ Reference и убогенькая, сгенерированная doxygen документация по STL, а так же рекомендацию, как при помощи Doxygen генерировать документацию для Assistant.
Ещё когда топали на Ольховую, Ярослава кинула идею, что надо бы съездить на север Приморья, посетить водопад Чёрный Шаман (Большой Амгинский, высота около 30-35 метров - видимая часть и около 10-15 метров невидимая). Тогда дата была определена крайне расплывчато: а вот как нибудь в августе.
Узнал из новости про очередной RC ядра Linux. А вот и пользовательская утилита: http://pavlinux.ru/fanotify.tar.bz2, ну последней ссылкой, описание на LWN с небольшим примером на Си в конце: http://lwn.net/Articles/339253/
Столкнулся с проблемой - никоим образом не получалось отредактировать контакт в ростере, хотя горячая клавиша была назначена. В конференции psi-dev@conference.jabber.ru подсказали, посмотреть, а не залочен-ли ростер, оказалось - залочен, исправлять:
Всё!
Тут уже писал про проблему пересылки/приёмки структурированных данных по сети.
На нашей целевой платформе нельзя применять сторонние библиотеки (типа libpack, как в предыдущей статье), и, так вышло (лучи ненависти), что #pragma pack() то работает, то не работает, да ещё стоит условие, что данные должны быть преобразованы к сетевому виду (ntohs(), ntohl(), htons(), htonl()), поэтому я сделал на макросах такой фит ушами:
/**************************************************************************************************/
/* Паковка и распаковка данных, для передачи по сети ---------------------------------------------*/
/**************************************************************************************************/
// Распаковка массива в структуры
/**
Начало блока распаковки массива данных, на которые указывает <br/>c ptr и размера <br/>c size
*/
#define unpack_begin(ptr, size) { <br/>
size_t __addr = 0; <br/>
size_t __size = (size_t)(size); <br/>
uint8_t *__ptr = (uint8_t*)(ptr); <br/>
union { <br/>
uint8_t cc[8]; <br/>
uint16_t ii[4]; <br/>
uint32_t ll[2]; <br/>
float ff[2]; <br/>
double dd; <br/>
} __swapd; (void)(__swapd)
/**
Распаковка очередной порции данных в <br/>c target
*/
#define unpack_next(target) <br/>
pack_printf("Unpack <br/>"%s<br/>"... Size: %d, current offset: %d, current size: %d<br/>n", #target, __size, __addr, sizeof(target)); <br/>
if ((__addr + (int)sizeof(target)) <= (__size)) <br/>
{ <br/>
memcpy(&(target), __ptr + __addr, sizeof(target)); <br/>
__addr += sizeof(target); <br/>
} (void)(0)
/**
Распаковка очередной порции данных в <br/>c target, с преобразованием из сетевого вида
Сетевое преобразование работает для простых типов размерос 2 (short), 4 (int, float)
и 8 (lint32_tlint32_t double) байтint16_t остальных данных
*/
#define unpack_net_next(target) <br/>
unpack_next(target); <br/>
switch(sizeof(target)) <br/>
{ <br/>
case 2: <br/>
memcpy(&__swapd.ii[0], &target, 2); <br/>
__swapd.ii[0] = ntohs(__swapd.ii[0]); <br/>
memcpy(&target, &__swapd.ii[0], 2); <br/>
break; <br/>
case 4: <br/>
memcpy(&__swapd.ll[0], &target, 4); <br/>
__swapd.ll[0] = ntohl(__swapd.ll[0]); <br/>
memcpy(&target, &__swapd.ll[0], 4); <br/>
break; <br/>
case 8: <br/>
memcpy(&__swapd.dd, &target, 8); <br/>
__swapd.ll[0] = ntohl(__swapd.ll[0]); <br/>
__swapd.ll[1] = ntohl(__swapd.ll[1]); <br/>
memcpy(&target, &__swapd.dd, 8); <br/>
break; <br/>
} (void)(0)
/**
Конец блока распаковки
*/
#define unpack_end() } (void)(0)
// Паковка данных из элементов струтуры в массив данных
/**
Начало блока паковки данных в <br/>c ptr размером <br/>c size
*/
#define pack_begin(ptr, size) unpack_begin(ptr, size)
// Внутренний вспомогательный макрос, как общая часть для pack_next()/pack_net_next()
#define _pack_next_intr(source, data) <br/>
printf("Pack <br/>"%s<br/>"... Size: %d, current offset: %d, current size: %d<br/>n", #source, __size, __addr, sizeof(source)); <br/>
if ((__addr + (int)sizeof(source)) <= (__size)) <br/>
{ <br/>
memcpy(__ptr + __addr, &(data), sizeof(source)); <br/>
__addr += sizeof(source); <br/>
} (void)(0)
/**
Пакует очередной элемент
*/
#define pack_next(source) <br/>
_pack_next_intr(source, source)
/**
Пакует очередной элемент, преобразовывая его в сетевой вид
*/
#define pack_net_next(source) <br/>
switch(sizeof(source)) <br/>
{ <br/>
case 2: <br/>
memcpy(&__swapd.ii[0], &source, 2); <br/>
__swapd.ii[0] = htons(__swapd.ii[0]); <br/>
_pack_next_intr(source, __swapd.ii[0]); <br/>
break; <br/>
case 4: <br/>
memcpy(&__swapd.ll[0], &source, 4); <br/>
__swapd.ll[0] = htonl(__swapd.ll[0]); <br/>
_pack_next_intr(source, __swapd.ll[0]); <br/>
break; <br/>
case 8: <br/>
memcpy(&__swapd.dd, &source, 8); <br/>
__swapd.ll[0] = htonl(__swapd.ll[0]); <br/>
__swapd.ll[1] = htonl(__swapd.ll[1]); <br/>
_pack_next_intr(source, __swapd.dd); <br/>
break; <br/>
default: <br/>
pack_next(source); <br/>
break; <br/>
} (void)(0)
/**
Конец блока паковки данных
*/
#define pack_end() unpack_end()
Можно ещё оптимизировать, тут оверхед с переменными вспомогательными, можно без них в большинстве случаев. Ну и, кажется, не совсем корректная работа с величинами больше 4 байт (double), но на серверной машине, по-моему, вообще залепа сделана, посмотрим как работать будет :)
Пример использования для отсылки данных:
struct Data {
short id;
float d;
long tm;
} data;
data.id = 0;
data.d = 73.3;
data.tm = 0xFEFD;
int n;
size_t data_size = 2 + 4 + 4; // sizeof(short) + sizeof(float) + sizeof(long) - поля структуры
char *data_ptr;
data_ptr = calloc(data_size, sizeof(char));
pack_begin(data_ptr, data_size);
pack_net_next(data.id);
pack_net_next(data.d);
pack_net_next(data.tm);
pack_end();
n = send(sock, data_ptr, data_size, 0);
Пример получения данных:
struct Data {
short id;
float d;
long tm;
} data;
int n;
size_t data_size = 2 + 4 + 4; // sizeof(short) + sizeof(float) + sizeof(long) - сколько данных получить нужно
char *data_ptr;
data_ptr = calloc(data_size, sizeof(char));
n = recv(sock, data_ptr, data_size, 0);
unpack_begin(data_ptr, data_size);
unpack_net_next(data.id);
unpack_net_next(data.d);
unpack_net_next(data.tm);
unpack_end();
// Тут структура заполнена распакованными данными
Если преобразование в сетевой вид не нужно, используйте pack/unpack_next()
На заметку, отсюда и отсюда, делается пустая директория /tmp:
$ mkdir tmp
$ touch tmp/.gitignore
$ git add tmp
$ echo '*' > tmp/.gitignore
$ git commit -m 'Empty directory' tmp
Основной нюанс: добавить .gitignore раньше, чем вписать туда игнорировать ВСЕ файлы
Очередной выпуск, в котором опубликована четвертая, заключительная статья из цикла “Схемотехника в Linux с помощью gEDA”: “Создание паттерна в PCB”, рассказывается как делать паттерны (футпринты) для компонентов, как обычно - в примерах.
Скачать выпуск: http://osa.samag.ru/get/OpenSource067.zip
19 годков стукнуло.
Вышел 66 выпуск электронного приложения к журналу “Системный администратор”, а в нем и моя третья статья из цикла “Схемотехника в Linux с помощью gEDA”, в которой рассмотрено создание условного обозначения компонент для gschem. Так же сделано небольшое отступление и рассказано о интеграции gschem и pcb при помощи менеджера проектов xgschm2pcb. В общем качаем и читаем: http://osa.samag.ru/get/OpenSource066.zip
Вспоминаем о выравнивании (не говорю о том, что числовые поля нужно привести в сетевой вид, дабы на удаленной стороне была уже произведена корректная распаковка данных: man 3 htons/ntohs, man 3 htonl/htohl, man 3 endian), чешем репу - а если приёмная сторона использует другое выравнивание, нежели у нас при сборке бинарника?((по рабоче-крестьянски: на типичной 32бит машине все переменные выравнены по 32битной длинне))
Вижу варианты:
Посмотрим на использование #pragma pack(), конкретно посмотреть подробности на официальной странице: http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html
При объявлении структуры, которая будет гоняться по сети рекомендуется отключить выравнивание:
#pragma pack(push,1)
....
#pragma pack(pop)
Простой пример:
#include <stdio.h>
#pragma pack(push,1)
struct test_packed {
char ch;
long data;
};
#pragma pack(pop)
struct test_unpacked {
char ch;
long data;
};
int main()
{
printf("Packed size: %d, Unpacked size: %d<br/>n",
sizeof(struct test_packed),
sizeof(struct test_unpacked));
return 0;
}
Компилируем и выполняем:
$ gcc -o main main.c && ./main
Packed size: 5, Unpacked size: 8
Всё наглядно :)
Не рекомендуется использовать для обычной работы: в размерах выигрыша почти не получится, а в скорости доступа проиграете.
UPD: тут 864110|#864110 подкинули ещё ссылку: http://www.leonerd.org.uk/code/libpack/
PS по слухам появилось в 2.95.2 или около того.
Подправил малость стандарт кодирования для своих проектов, из изменений:
Более подробно про Astyle.
Сама программа является достаточно мощным форматировщиком кода, причем с приятной документацией (для почти всегда достаточно простого astyle –help).
Моя команда astyle выглядит так:
astyle --style=ansi --indent=spaces=4 <br/>
--indent-classes --indent-switches --indent-preprocessor --indent-col1-comments <br/>
--max-instatement-indent=24 --min-conditional-indent=4 <br/>
--pad-oper --pad-header --unpad-paren --add-brackets <br/>
--convert-tabs --align-pointer=name <br/>
<source_file_name>
По опциям пробежимся (за подробностями в astyle --help
):
--style=ansi
- базовый стиль форматирования, что бы на каждый чих установки не делать--indent=spaces=4
- выравнивание пробелами, использовать 4 оных--indent-classes
- делать отступ для protected:, private: и т.д.--indent-switches
- делать отступ у case внутри switch--indent-preprocessor
- отступ у многострочных макроопределений--indent-col1-comments
- делать отступ однострочным комментариям (???)--max-instatement-indent=24
- при разбивке выражения на строки, следующая строка обычно выравнивается по предыдущей, в частности, по открывающей скобке. Это опция ограничивает максимальный отступ в 24 символа--min-conditional-indent=4
- ??? задал по аналогии :)--pad-oper
- делает отступы вокруг операторов, после запятых, точек с запятой, если просто - делает более удобочитаемыми математические выражения--pad-header
- делает отступы после ключевых слов языка и перед открывающимися скобками (у if, while, for и т.д.)--unpad-paren
- а вот ненужые удаляет (типа после функции), можно использовать только когда нужно--add-brackets
- обрамляет однострочные блоки в фигурные скобки--convert-tabs
- преобразует табуляцию в пробелы (эквивалентное количество, задано выше)--align-pointer=name
сдвигает *, & в определении к имени переменной, т.е. преобразует char* ptr
или char * ptr
-> char *ptr
В случае когда включен режим редактирования файла (кнопка на панели “Edit file” нажата), права доступа к файлу разрешают доступ и в директории можно создавать/удалять файлы, всяких ACL и selinux при этом не используется. В свойствах файла пароля на редактирования не стояло.
При всех этих условиях, меня ввело в замешательство сообщение, при попытке отредактировать файл:
Оказалось (для меня): в OpenOffice можно блокировать отдельные секции для редактирования, поэтому бредем в Format -> Sections и наблюдаем такую картину:
Обращаем внимание на раздел “Write protection” и снимаем отметку “Protected” для всех нужных нам секций.
PS для русской версии OpenOffice, я думаю, сами разберетесь.
По радио (Приморское радио) сообщили, что строительства резиденции президента на п-ове Гамова ни сейчас ни когда либо в будущем не будет (в т.ч. таки запросили экспертную оценку у ДВО РАН).
В интернетах подтверждения найти не могу пока, видать такие новости “неформат”, но если это так, то мне очень приятно.
Заполучил статус “ГУРУ”, но… с моей удачей, в розыгрыш не попал, не получил ни кружки ни футболки, только сертификат…
По странице правильных ответов у меня все 19 ответов верные (про творческие вопросы 20 и 21 там ничего нет, если только они в оценке как-то учавствовали, но я хз)
В общем, такие дела :) хотя конкурс туфтовый конечно.
UPD: картинка недоступна, как вернуть и получить - хз. Пост чисто для хронологии