LINUX.ORG.RU

Сообщения Dendy

 

Разработка KDE

Решил сделать доброе дело и отправить патч в KDE. Снабдил описанием, добавил тесты, проверил локально. Нашёл базовый коммит, начиная с которого будет совместимо моё изменение и ребейзнулся на него. Здесь меня начали терзать смутные сомнения, ведь кроме единственной удалённой ветки origin/master в проекте были только теги. Оригинал был взят из github/KDE.

Собственно, при попытке сделать pull-request в github, я был послан на... kde.org с извинениями, мол github только хостит зеркало, следуй официальному процессу, молодой падаван^Wконтрибьютор.

И тут меня как окатило ледяным душем: они просят прислать diff-файл. Протёр глаза, ущипнулся, сверился с календарём — 2018-й подходит к концу, перевёл глаза обратно в монитор. Дальнейшие действия были машинальны, создал аккаунт, сделал им diff, выковырял из коммита описание и отправил патч, завершив свою часть квеста.

ЛОР, есть ли среди тебя разработчики KDE, подтвердить они действительно так и пишут KDE, обмениваясь diff-ами?

 

Dendy ()

Подсветка в Kate

Пытаюсь наваять подсветку в своём языке следуя документации: https://docs.kde.org/stable5/en/applications/katepart/highlight.html

Столкнулся с простейшей проблемой, которую ну никак не получается обойти, десятки примеров подсветки для существущих языков прозрения не добавляют.

К примеру, есть синтаксис, для которого написаны контекст и правила:

foo=bar

Такой синтаксис применяется во многих местах, в документации для этого предусмотрен вход/выход в контекст, а также включение существующего правила в текущий контекст. Вот только при выныривании из подобного правила оно может быть применено снова. Как следствие подобные конструкции за ошибку не будут считаться:

foo=bar foo=bar

Хотя по правилам языка между ними должна быть запятая. Можно создать контекст, который будет сначала требовать запятую. Но никак не могу понять, как существующее правило foo=bar должно в него вернуться, ведь единственный предусмотренный способ это #pop.

Есть вариант сделать #pop!my_context_with_leading_coma. Но возвращаемся к нашим баранам — правило foo=bar повторяется в совершенно разных местах, каждый из которых имеет свой синтаксис, то-есть !my_context_with_leading_coma это частный случай и захардкодить его нельзя.

Признавайся, ЛОР, ты занимался раскраской кода в Kate?

 , ,

Dendy ()

Япония, (анти?)утопия

Смотрел с десяток лет назад. Будущее. Завязка мультфильма в полной блокаде Японии изнутри, ни связи, ни физического доступа, ни наружного наблюдения на протяжении многих лет. Терра инкогнита. Там живут драконы. И вот туда засылается отряд, обнаруживающий...

Прошу прощения, если путаю что-то в сюжете. Пытаюсь вспомнить название.

 ,

Dendy ()

Указать версию C++ в QtCreator

QtCreator 4.7+, Clang code model. Конструкции C++ не разбираются, первое на что ругается парсер, что __cplusplus < 201103L, то-есть версия C++ выбрана не та. Нигде в настройках не существует опции, чтобы указать версию C++, которая используется в проекте.

Интернет ноет, на открытые баги в трекере никто не отвечает. На форумах глупые подсказки типа пропиши у себя в .pro-файле что-то там. Никаких .pro-файлов, конечно же не существует, равно как и CMakeLists.txt и т.п.

До 4.6 вроде работал хак, позволяющий вписать -std=c++11 в командную строку с предупреждениями, которая передаётся в clang. Но теперь там стоит sanity check, ругающийся что аргумент не есть warning, а значит будет отфильтрован. А никакой замены этому не сделали.

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

 ,

Dendy ()

Перегрузка оператора <<

Есть класс S с шаблонным оператором <<. Вызывается он из другой шаблонной функции run(), которая инстанциируется в main(). При этом есть перегрузка оператора << с типом MyValue, объявленная до самого main(). То-есть в момент инстанциации (тьфу что за слово такое) шаблона run() видны дефолтный метод (S::operator<<()) и перегруженный и компилятор должен выбрать перегруженный. GCC так и делает, но Clang всё равно игнорирует перегрузку и вызывает дефолтный метод.

При этом если объявить перегруженный метод до объявления шаблона run() (путём простого перемещения #include «run.h» пониже), то Clang начинает работать как и положено, то-есть вызывать перегруженный метод.

Кто прав, кто виноват, и как сие чинить, чтобы был порядок и все компиляторы были счастливы?

run.h

#include <stdio.h>

struct S {
    template <typename T>
    void operator<<(T) { printf("DEFAULT\n"); }
};

namespace N {
template <typename T>
void run(const T & value) { S s; s << value; }
}

main.cpp (работает в GCC, не работает в clang)

#include "run.h"

struct MyValue {};

namespace N {
void operator<<(S&, MyValue) { printf("OVERLOADED\n"); }
}

int main(int, char**)
{
	N::run(MyValue());
	return 0;
}

main.cpp (работает и там, и там, #include «run.h» передвинут под перегрузку оператора <<)

#include <stdio.h>

struct S;
struct MyValue {};

namespace N {
void operator<<(S&, MyValue) { printf("OVERLOADED\n"); }
}

#include "run.h"

int main(int, char**)
{
	N::run(MyValue());
	return 0;
}

 ,

Dendy ()

Вспомнить фантастический рассказ

Короткий рассказ, читал в далёком детстве. Учёный изобретает машину времени, но которая не перемещает вещи во времени/пространстве, а эволюционирует всё, что в неё помещается. К примеру, если поместить червяка, то он может трансформироваться в, скажем, в змею, как если бы за него это сделала эволюция через N лет. И этот учёный решает поместить в машину себя, чтобы узнать каким станет человек будущего.

 

Dendy ()

Адаптивная обфускация

Навеяно новостями про Телеграм и маниакальным желанием властей читать чужую переписку. Если посмотреть на проблему с юридической точки зрения, то формально предъявить Телеграму нечего — у него действительно нет ключей шифрования, они находятся на стороне пользователя, который сам решает в каком виде общаться с собеседником. Можно сказать, что зашифрованное сообщение есть лексикон, на котором общаются люди, ну а то что ФСБ этот язык не понимает только их проблемы. Собственно, об этом известный художественный фильм «Говорящие с ветром». Принуждение к переписке на определённом языке это прямое нарушение Конституции РФ Статья 26.2. Но поскольку властям откровенно плевать на свои же законы, то имеем что имеем.

Очевидно, что кто хочет зашифроваться, тот это сделает, причём будет строить свои коварные планы под носом спецслужб и единственные, по кому может ударить запрет мессенжеров — обычные пользователи.

Собственно, к вопросу технической реализации подобного шифрования. Допустим, шпионская программа полностью прослушивает трафик на предмет подозрительных слов. Если она обнаруживает билиберду вместо читабельного текста это повод задуматься не было ли оно зашифровано. Задача — сделать закодированное сообщение читаемым на родном языке, причём имеющее смысл, связную речь, опечатки и жаргон. Вобщем всё, чтобы для mitm выглядело как будто общаются два реальных человека. В то время как на стороне конечных пользователей сообщения будут показываться в их первозданном виде.

Шифрованные и нешифрованные сообщения могут перемеживаться (пользователь сам переключает режим по необходимости). Из нешифрованных на лету составляется словарь, на основе которого будет генерироваться закодированный текст, чтобы даже со стороны было похоже, что люди не на случайные темы общаются. К примеру, ты говоришь: «Сходил вчера в кино на Гарри Поттера», а тебе отвечают: «А в каком году вышла книга про Поттера?», что автоматически расшифровывается в нечто: «собираемся бухать в 9».

Канал для доставки сообщений может использоваться любой: почта, мессенжеры, соцсети и т.п. Сообщения видны в зашифрованном виде до момента, когда человек явно введёт в программу свой пароль-ключ на время сессии. То-есть даже при доступе к физическому носителю данных ничего подозрительного на нём не найдут. Полная противоположность когда ФС или трафик явно зашифрованы, и спецслужбы могут вежливо попросить ключики у пользователей с помощью терморектального криптоанализа. Или вообще забанить подобный мессенжер.

Когда-то давно читал историю как научный журнал опубликовал статью, сочиненную компьютером. Собственно, что мешает адаптировать наработки и есть ли прецеденты?

 , ,

Dendy ()

Разработчиков openSUSE отпустило

Целых два года мейнтейнеры знали ответ на главный вопрос жизни, вселенной и вообще. Пока полиция Аргентины наконец не прекратила это безобразие.

  • 10.0 → 10.1 → 10.2 → 10.3
  • 11.0 → 11.1 → 11.2 → 11.3 → 11.4
  • 12.1 → 12.2 → 12.3
  • 13.1 → 13.2
  • 42.1 → 42.2 → 42.3
  • 15.0

 

Dendy ()

Фантастика

Навеяно современным сиквелом «Бегущий по лезвию», а также оригиналом, который пришлость пересмотреть. Очень напомнило роман одного из фантастов моего детства (Роберт Хайнлайн?), но не могу вспомнить ни название, ни автора.

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

 

Dendy ()

Задачки по программированию

Некоторое время назад гуглил что-то по программированию и вместо результатов поиска гугл загадочно спросил: «Хочешь поиграть?», на что я ответит утвердительно и перешёл на страницу с задачками по программированию, видимо разработанную самим большим братом.

К сожалению, страница была утеряна, пытаюсь вспомнить что это был за сайт. Получение и выполнение заданий было через виртуальный терминал с ограниченным набором команд. Там же можно было писать код, выполнять его. Когда уверен, что задачка решена, то комитишь результат, который прогоняется тестами, после чего выдаётся новое задание.

Вроде сайт был даже под доменом google.com, но не уверен.

 ,

Dendy ()

KSysGuard

Наболело. Монитор ресурсов всегда был неотъемлемой частью десктопа. Поскольку пользуюсь KDE разных версий, то время от времени запускаю KSysGuard наблюдать кто чего отожрал. И всё больше поражаюсь неадекватности его авторов, поскольку с годами ничего не меняется. А именно дефолтный системный монитор KDE как правило отжирает больше ресурсов, чем процессы, которые он должен мониторить. Я один чего-то непонимаю в современных тенденциях, но мне всегда казалось, что программа мониторинга должна выживать в условиях полного саботажа системы, когда ушла вся память, процессор загружен на 100%, а радиатор видеокарты раскалился докрасна. Потреблять минимум ресурсов, не аллоцировать память в бесконечных циклах, не использовать двойной буферизации при отрисовке, отказаться от шашечек вроде красивых графиков со сглаживанием и градиентами. Но видимо авторы KSysGuard имеют другое представление.

К чему это я. Кто какой использует графический системный монитор на десктопе, желательно не привязанный к ДЕ, мгновенно запускающийся и потребляющий минимум ресурсов?

 

Dendy ()

MIT, GPL и сублицензии

Есть permissive-лицензия на некий проект, допустим, MIT. Могу ли я взять оттуда код и выпустить его под GPL? Или под двойной коммерческой лицензией, как тот же Qt?

Вот, к примеру, отрывок из MIT:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

А вот отрывок из Википедии по поводу permissive для Apache, который противоречит вышесказанному:

The Apache License is permissive in that it does not require a derivative work of the software, or modifications to the original, to be distributed using the same license

Тут я обратил внимание на строчку sublicense:

Permission is hereby granted ... including without limitation the rights to ... sublicense

Но первые две ссылки в гугле что такое это sublicense прямо противоречат друг другу:

a license granted to a third party by a licensee, extending some rights or privileges that the licensee enjoys.

A license is an agreement by which the owner of something grants, to someone else, rights that are less that all of the rights to that thing.

Где правда?

Могу ли я просто взять и заменить лицензию на код, выпущенный, к примеру, под MIT? А если нет и я обязан везде указывать лицензию MIT, то как это отличается от вирусных лицензий? К примеру, правлю я неспеша код, промежуточные версии обязан выпускать с шапкой MIT, потому что это мне навязано substantial portion. К тому времени, как от оригинального кода не останется и строчки, он всё равно обязан быть выпущен под MIT, поскольку так гласят промежуточные версии?

P.S. Да, я понимаю, что искать смысл в лицензиях это как учить рыбу ходить за ручку пешком, но тем не менее.

 , , ,

Dendy ()

Уникальный умный указатель без семантики копирования/перемещения

Есть ли в стандартной библиотеке класс указателя для уникального владения, но без семантики перемещения? Ищу замену, к примеру, такому коду:

class A {
public:
  A() { d = new AImpl; }
  ~A() { delete d; }
};

unique_ptr для такой задачи избыточен: имеет семантику перемещения, хранит deleter, выполняет лишнюю проверку в рантайме на валидность указателя.

Нужно буквально нечто такое:

template <typename T>
class Ref {
public:
  Ref(T & r) : r(r) {}
  ~Ref() { delete &r; }
  T & r;
};

 

Dendy ()

Конфигурация сборки

Изучаю возможности сборки Android-приложения через Gradle, после CMake возникают элементарные вопросы по конфигурации. Собственно, есть ли вообще этап конфигурации в Gradle, наподобие ./configure <options> или cmake <options>?

Вот тривиальный пример: Android-плагин хочет знать где лежит SDK, но делает это странным способом. Нужно либо указать путь к SDK в переменной окружения ANDROID_HOME, либо создать файл local.properties со строкой sdk.dir=<path/to/sdk>. Первый вариант не годится по очевидной причине, что для каждого приложения необходимо создавать враппер для вызова сборки, в котором будет указана переменная ANDROID_HOME для текущего пользователя. Второй вариант тоже не подходит, потому как local.properties должен лежать в директории с исходным кодом вместо директории сборки, если нужно собирать приложение с разными SDK, то неясно как между ними переключаться. Естественно ни враппер, ни local.properties в систему контроля версий не сохраняются, потому как содержат локальные пути.

В Gradle можно передать параметры сборки в командной строке, но по каким-то причинам Android-плагин игнорирует этот способ.

В CMake путь к SDK указался бы при конфигурации в командной строке (или нашёлся бы автоматически) и сохранился один раз в кеш, после чего сборка проекта проходит простым вызовом ninja без аргументов и ненужных врапперов.

Какой идеологически верный способ конфигурировать проект в Gradle? Есть ли вообще способ экспортировать переменные наружу, чтобы пользователь при сборке мог их переопределить?

 ,

Dendy ()

Ситуация с архиваторами в Линуксе и вообще

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

  • zip — отдельная компрессия каждого файла, вследствие чего размер архива неприлично большой;
  • tar.gz — ограничение на длину файла в 100 (!) символов, отсутствие директории содержимого, как результат невозможно просмотреть содержимое архива без его распаковки;
  • 7z — не сохраняет права на файлы;
  • rar — проприетарщина, насколько понимаю также не сохраняет права.

Поправьте если я в чём-то ошибаюсь. Существует ли в принципе популярный архиватор без вышеуказанных проблем, которым пользуется не только его автор?

 ,

Dendy ()

PIMPL без указателя

Всем хорошо известен паттерн PIMPL через скрытие реализации за указателем. С известными же проблемами неоптимального исполнения, когда нужно дополнительно аллоцировать память под сам указатель. Сходу нашёл в интернете варианты вместо указателя использовать заранее большой массив, на котором вызывается placement new, но такой подход вызывает ещё больше вопросов.

В самом C++ для скрытия реализации есть абстрактные интерфейсы без данных, реализация которых создаётся через фабрику или статический метод вместо конструктора. Однако с абстрактными интерфейсами одна беда — если наследовать один интерфейс от другого, то их реализации будут иметь ромбовидное наследование — один раз от наследуемого интерфейса, второй раз от реализации базового интерфейса. Ложку дёгтя добавляет необходимость замены конструкторов фабриками и руками делать правильные вызовы родительских конструкторов. Добавим сюда необходимость писать для каждого класса фактически два: один обстрактный, второй с реализацией. Получим достаточно неудобный подход, недостатки которого устраняет PIMPL.

Возьмём к примеру библиотеку Qt, объектная модель которой полностью построена на PIMPL и наследовании от базового QObject. При этом сами объекты на стеке или по значению создаются крайне редко, в повальном случае экземпляры QObject выделяются в куче. Получаем двойную аллокацию: первую для самого указателя, вторую для данных по указателю. Также при использовании подобных экземпляров будет двойное разименование, что также негативно скажется на производительности. При этом подсознательно понимаешь, что подобный подход бессмысленнен, ведь PIMPL-указатель никогда не подменяет реализацию на этапе выполнения, он создаётся исключительно в конструкторе и удаляется исключительно в деструкторе объекта.

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

Вот простой пример, нарисованный на коленке:

#pragma once

#include <cstddef>

class A
{
public:
	A(int value = 42);

	int value() const;
	void setValue(int value);

	DECLARE_PRIVATE(A)
};

class B : public A
{
public:
	B(int data);

	int data() const;

	DECLARE_PRIVATE(B)
};
#include "lib.h"

class A::Private
{
public:
	int value;
};
DEFINE_PRIVATE(A)

A::A(const int value)
{
	to_private()->value = value;
}

int A::value() const
{
	return to_private()->value;
}

void A::setValue(const int value)
{
	to_private()->value = value;
}


class B::Private : public A::Private
{
public:
	int data;
};
DEFINE_PRIVATE(B)

B::B(const int data)
{
	to_private()->data = data;
}

int B::data() const
{
	return to_private()->data;
}

DECLARE_PRIVATE и DEFINE_PRIVATE переопределяют операторы new и delete и определяют методы приведения реализации к интерфейсу:

#define DECLARE_PRIVATE(T) \
public: \
	void * operator new(std::size_t size); \
	void operator delete(void * ptr); \
	class Private; \
private: \
	const Private * to_private() const { return reinterpret_cast<const Private*>(this); } \
	Private * to_private() { return reinterpret_cast<Private*>(this); }

#define DEFINE_PRIVATE(T) \
	void * T::operator new(const std::size_t size) \
	{ \
		return new Private; \
	} \
	\
	void T::operator delete(void * const ptr) \
	{ \
		delete static_cast<Private*>(ptr); \
	}

Ограничения данного подхода очевидны: объекты нельзя создавать на стеке или в виде переменной-члена класса. Аллоцировать их можно только через new, к примеру:

std::unique_ptr<B> b(new B(95));
b->setValue(33);

Сравним с традиционным подходом в Qt:

  • Объявление класса: Qt — Q_DECLARE_PRIVATE(classname), в нашем случае то же самое — DECLARE_PRIVATE(classname).
  • Определение класса: Qt — наследование реализации, то же самое у нас + DEFINE_PRIVATE(classname).
  • Аллокация класса: Qt — явный вызов базового класса с передачей указателя на реализацию
    MyObject::MyObject() : MyParentObject(*new MyObjectPrivate)
    у нас — неявный вызов базового класса без лишних телодвижений.
  • Обращение к реализации: Qt — d_func(), у нас — to_private().
  • Аллокация объекта в куче: Qt — две аллокации, в нашем случае — одна.
  • Аллокация объекта на стеке: Qt — одна аллокация, в нашем случае тоже одна, через явный operator new.

Осталось только понять как запретить создавать объекты на стеке на этапе компиляции, но это уже детали.

Я догадываюсь, что всё выше есть велосипед, но почему-то я нигде не встречал подобной реализации (кроме исходников Андроида). Собственно, какие у есть минусы у данного подхода? Какие известные проекты практикуют подобный подход вместо традиционного PIMPL?

 

Dendy ()

Найти старый клип Black Hawk Down

Музыкальный клип одной рок группы с видеорядом из фильма Black Hawk Down, достаточно старый, смотрел его лет 12 назад. Музыка не из официальных саунд треков. Возможно даже клип был создан любителями, но был достаточно популярен в своё время. Название исполнившей песню группы крутится на языке, но вспомнить никак не выходит.

 ,

Dendy ()

Распознавание жестов пальцев на экране

Нужна библиотека на C/C++ для распознавания жестов мышью и нескольких пальцев на тач-скрине. С возможностью расширения библиотеки жестов, распознавания букв и символов, обучения. Или помогите составить запрос в гугл, потому что мне по «gesture recognition library» выдаёт всё что угодно, кроме желаемого.

 

Dendy ()

Вышел QtCreator 3.5 rc1

В котором наконец заработало разименовывание std::unique_ptr: https://download.qt.io/development_releases/qtcreator/3.5/3.5.0-rc1

 ,

Dendy ()

Сломан предпросмотр при ответе на сообщение

При попытке вставить в ответ на сообщение список с элементами предпросмотр показывает символы разметки вместо самого списка. Если же игнорировать предпросмотр и ответить, то в результирующем сообщении показывается уже правильно. Также предпросмотр показывается правильно при правке сообщения, когда он открывается в отдельном окне. Не работает именно встроенный предпросмотр, который открывается под сообщением, на которое отвечаешь.

 ,

Dendy ()

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