Merge branch 'asciidoc'

This commit is contained in:
Andrei Astafev 2019-06-03 10:04:55 +03:00
commit 3b34f960b5
90 changed files with 3258 additions and 3034 deletions

3
.gitignore vendored
View File

@ -1,4 +1,5 @@
cache/*
cache-ascii/*
cache-full/*
cache-html/*
output/*
@ -6,4 +7,6 @@ __pycache__
wiki/trash
wiki/notes.sqlite
upload.sh
wiki/**/*.png
wiki/**/*.png.cache

3
.gitmodules vendored
View File

@ -23,3 +23,6 @@
[submodule "plugins/thirdparty/replacer"]
path = plugins/thirdparty/replacer
url = git@github.com:/narusemotoki/replacer
[submodule "plugins/thirdparty/asciidoctor"]
path = plugins/thirdparty/asciidoctor
url = git@git.246060.ru:f1x1t/pelican-asciidoctor

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# -*- coding: utf-8 -*- #
from __future__ import unicode_literals
import os
class i18n(object):
# looks for translations in
@ -54,23 +55,12 @@ AUTHOR_FEED_RSS = None
USE_FOLDER_AS_CATEGORY = True
DEFAULT_DATE = 'fs'
STATIC_PATHS = [ 'images', 'files', 'extras' ]
DIRECT_TEMPLATES = ('index', 'categories', 'authors', 'archives', 'search')
EXTRA_PATH_METADATA = {
'extras/favicon.ico': {'path': 'favicon.ico'},
}
MARKDOWN = {
'extension_configs': {
'markdown.extensions.codehilite': {'css_class': 'highlight'},
'markdown.extensions.extra': {},
'markdown.extensions.meta': {},
'markdown.extensions.toc': {
'title': 'Содержание'
},
} ,
'output_format': 'html5',
}
DISPLAY_CATEGORIES_ON_MENU = False
DISPLAY_CATEGORIES_ON_SIDEBAR = True
DISPLAY_TAGS_ON_SIDEBAR = True
@ -85,50 +75,31 @@ I18N_GETTEXT_DOMAIN = 'messages'
JINJA_ENVIRONMENT = {'extensions': ['jinja2.ext.i18n']}
PLUGIN_PATHS = ["plugins/official", "plugins/thirdparty"]
PLUGINS = [i18n(), "pandoc_reader", "pelican-css", "pelidoc", "series", "subcategory", "tag_cloud", "tipue_search", "plantuml", "replacer"]
#PLUGINS = ["better_tables", "just_table"]
PLUGINS = [i18n(), "pelican-css", "series", "subcategory", "tag_cloud", "tipue_search", "replacer", "asciidoctor"]
PDF_PROCESSOR = True
PANDOC_OUTPUTS = {
'pdf': 'pdf',
}
PANDOC_ARGS = [
"--variable=documentclass:extarticle",
"--variable=toc-title:Содержание",
"--filter=skip-toc-tag",
"--filter=pandoc_plantuml_filter.py",
"--highlight-style=tango",
"--template=wiki",
"--resource-path=wiki:."
ASCIIDOCTOR_CMD = "asciidoctor"
ASCIIDOCTOR_EXTRA_OPTIONS = [
'--require', 'asciidoctor-diagram',
'--attribute=imagesdir={}/wiki/images'.format(os.getcwd()),
'--attribute=source-highlighter=pygments',
'--attribute=pygments-style=manni',
'--attribute=pygments-css=class',
'--attribute=lang=ru',
'--attribute=figure-caption=Рис.',
'--attribute=toc-title=Содержание',
'--attribute=experimental',
]
PANDOC_EXTRA_OPTIONS = PANDOC_ARGS + [ "--pdf-engine=xelatex" ]
PANDOC_MARKDOWN_EXTENSIONS = [
"+smart",
"+backtick_code_blocks",
"+fenced_code_blocks",
"+fenced_code_attributes",
"+fenced_divs",
"+native_divs",
"+bracketed_spans",
"+native_spans"
]
PANDOC_EXTENSIONS = PANDOC_MARKDOWN_EXTENSIONS
REPLACES = (
(u'output/images/', u'images/'),
('{}/wiki/'.format(os.getcwd()), u''),
)
YUICOMPRESSOR_EXECUTABLE = "yui-compressor"
YUICOMPRESSOR_EXTRA_OPTIONS = ["--nomunge"]
PLUGINS += ["yuicompressor-opt"]
DIRECT_TEMPLATES = ('index', 'categories', 'authors', 'archives', 'search')
PDF_PROCESSOR = True
# Blogroll
LINKS = ()
@ -142,7 +113,7 @@ SOCIAL = ()
# SOCIAL = (('You can add links in your config file', '#'),
# ('Another social link', '#'),)
PYGMENTS_STYLE='pastie'
PYGMENTS_STYLE='asciidoctor-pastie'
DEFAULT_PAGINATION = 20

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# -*- coding: utf-8 -*- #
from __future__ import unicode_literals
import os
class i18n(object):
# looks for translations in
@ -35,7 +36,7 @@ SITENAME = 'ДСП'
SITEURL = 'https://dsp.246060.ru'
PATH = 'wiki'
CACHE_PATH = 'cache-html'
CACHE_PATH = 'cache'
TIMEZONE = 'Europe/Moscow'
@ -54,23 +55,12 @@ AUTHOR_FEED_RSS = None
USE_FOLDER_AS_CATEGORY = True
DEFAULT_DATE = 'fs'
STATIC_PATHS = [ 'images', 'files', 'extras' ]
DIRECT_TEMPLATES = ('index', 'categories', 'authors', 'archives', 'search')
EXTRA_PATH_METADATA = {
'extras/favicon.ico': {'path': 'favicon.ico'},
}
MARKDOWN = {
'extension_configs': {
'markdown.extensions.codehilite': {'css_class': 'highlight'},
'markdown.extensions.extra': {},
'markdown.extensions.meta': {},
'markdown.extensions.toc': {
'title': 'Содержание'
},
} ,
'output_format': 'html5',
}
DISPLAY_CATEGORIES_ON_MENU = False
DISPLAY_CATEGORIES_ON_SIDEBAR = True
DISPLAY_TAGS_ON_SIDEBAR = True
@ -85,50 +75,31 @@ I18N_GETTEXT_DOMAIN = 'messages'
JINJA_ENVIRONMENT = {'extensions': ['jinja2.ext.i18n']}
PLUGIN_PATHS = ["plugins/official", "plugins/thirdparty"]
PLUGINS = [i18n(), "pandoc_reader", "pelican-css", "pelidoc", "series", "subcategory", "tag_cloud", "tipue_search", "plantuml", "replacer"]
#PLUGINS = ["better_tables", "just_table"]
PLUGINS = [i18n(), "pelican-css", "series", "subcategory", "tag_cloud", "tipue_search", "replacer", "asciidoctor"]
#PDF_PROCESSOR = True
PANDOC_OUTPUTS = {
'pdf': 'pdf',
}
PANDOC_ARGS = [
"--variable=documentclass:extarticle",
"--variable=toc-title:Содержание",
"--filter=skip-toc-tag",
"--filter=pandoc_plantuml_filter.py",
"--highlight-style=tango",
"--template=wiki",
"--resource-path=wiki:."
ASCIIDOCTOR_CMD = "asciidoctor"
ASCIIDOCTOR_EXTRA_OPTIONS = [
'--require', 'asciidoctor-diagram',
'--attribute=imagesdir={}/wiki/images'.format(os.getcwd()),
'--attribute=source-highlighter=pygments',
'--attribute=pygments-style=manni',
'--attribute=pygments-css=class',
'--attribute=lang=ru',
'--attribute=figure-caption=Рис.',
'--attribute=toc-title=Содержание',
'--attribute=experimental',
]
PANDOC_EXTRA_OPTIONS = PANDOC_ARGS + [ "--pdf-engine=xelatex" ]
PANDOC_MARKDOWN_EXTENSIONS = [
"+smart",
"+backtick_code_blocks",
"+fenced_code_blocks",
"+fenced_code_attributes",
"+fenced_divs",
"+native_divs",
"+bracketed_spans",
"+native_spans"
]
PANDOC_EXTENSIONS = PANDOC_MARKDOWN_EXTENSIONS
REPLACES = (
(u'output/images/', u'images/'),
('{}/wiki/'.format(os.getcwd()), u''),
)
YUICOMPRESSOR_EXECUTABLE = "yui-compressor"
YUICOMPRESSOR_EXTRA_OPTIONS = ["--nomunge"]
#PLUGINS += ["yuicompressor-opt"]
DIRECT_TEMPLATES = ('index', 'categories', 'authors', 'archives', 'search')
#PDF_PROCESSOR = True
# Blogroll
LINKS = ()
@ -142,7 +113,7 @@ SOCIAL = ()
# SOCIAL = (('You can add links in your config file', '#'),
# ('Another social link', '#'),)
PYGMENTS_STYLE='pastie'
PYGMENTS_STYLE='asciidoctor-pastie'
DEFAULT_PAGINATION = 20

@ -1 +1 @@
Subproject commit cfc7a3f224f1743063b034561f89a6a712d13587
Subproject commit 8cea2c6492f98e11341c48556978da7f6756f8a0

1
plugins/thirdparty/asciidoctor vendored Submodule

@ -0,0 +1 @@
Subproject commit 9e0019a728113f8502d04eeca8bf2682219086b6

@ -1 +1 @@
Subproject commit 4471139a1a419abc4e2aa94c09f0ef7550c65b00
Subproject commit ce6b18660a933855dbe996fc5b5d3d0ac1c25223

View File

@ -0,0 +1,12 @@
= LaTeX: висячие строки
:title-separator: {sp}|
:category: LaTeX
:tags: LaTeX, текст,
Пакет https://www.ctan.org/pkg/nowidow[`nowidow`] используется для
изменения алгоритма размещения висячих строк. Пример:
[source,latex]
----
\usepackage[defaultlines=3,all]{nowidow}
----

View File

@ -1,14 +0,0 @@
---
title: "LaTeX: висячие строки"
category: LaTeX
tags: LaTeX, текст,
summary:
...
Пакет [`nowidow`](https://www.ctan.org/pkg/nowidow) используется для
изменения алгоритма размещения висячих строк. Пример:
```latex
\usepackage[defaultlines=3,all]{nowidow}
```

View File

@ -0,0 +1,105 @@
= LyX: редактирование ЕСПД
:title-separator: {sp}|
:category: LaTeX
:tags: LaTeX, текст, LyX,
Установить пакеты:
[source,sh]
----
sudo apt-get install lyx texlive-xetex
----
Установить стили LaTeX для http://tiny.cc/u8eo7y[ЕСПД]:
[source,sh]
----
git clone https://git.246060.ru/f1x1t/latex-style-esdpx ~/texmf/tex/latex/espdx
----
Установить шаблоны для LyX:
[source,sh]
----
git clone https://git.246060.ru:/f1x1t/lyx-layout-espdx.git ~/.lyx/layouts
----
Запустить LyX и в меню выбрать menu:Инструменты[Обновить конфигурацию] и
перезапустить программу.
Скачать link:files/espdx-template.lyx[шаблон] для LyX, открыть файл
*espdx-template.lyx* и в меню выбрать menu:Документ[Настройки…].
В появившемся окне нажать кнопку btn:[Сохранить как параметры
документа по умолчанию].
Пример настройки:
[.text-center]
.Класс документа
image::lyx-espdx/01.png[Класс документа]
[.text-center]
.Модули
image::lyx-espdx/02.png[Модули]
[.text-center]
.Шрифты
image::lyx-espdx/03.png[Шрифты]
[.text-center]
.Макет текста
image::lyx-espdx/04.png[Макет текста]
[.text-center]
.Макет страницы
image::lyx-espdx/05.png[Макет страницы]
[.text-center]
.Поля страницы
image::lyx-espdx/06.png[Поля страницы]
[.text-center]
.Язык
image::lyx-espdx/07.png[Язык]
[.text-center]
.Нумерация и содержание
image::lyx-espdx/08.png[Нумерация и содержание]
[.text-center]
.Библиография
image::lyx-espdx/09.png[Библиография]
[.text-center]
.Предметный указатель
image::lyx-espdx/10.png[Предметный указатель]
[.text-center]
.Свойства PDF / Общие
image::lyx-espdx/11.png[Свойства PDF / Общие]
[.text-center]
.Свойства PDF / Гиперссылки
image::lyx-espdx/12.png[Свойства PDF / Гиперссылки]
[.text-center]
.Свойства PDF / Закладки
image::lyx-espdx/13.png[Свойства PDF / Закладки]
[.text-center]
.Параметры математики
image::lyx-espdx/14.png[Параметры математики]
[.text-center]
.Размещение плавающих объектов
image::lyx-espdx/15.png[Размещение плавающих объектов]
[.text-center]
.Форматы
image::lyx-espdx/16.png[Форматы]
[.text-center]
.Преамбула LaTeX
image::lyx-espdx/17.png[Преамбула LaTeX]

View File

@ -1,69 +0,0 @@
---
title: "LyX: редактирование ЕСПД"
category: LaTeX
tags: LaTeX, текст, LyX,
summary:
...
Установить пакеты:
```sh
sudo apt-get install lyx texlive-xetex
```
Установить стили LaTeX для ЕСПД:
```
git clone https://git.246060.ru/f1x1t/latex-style-esdpx ~/texmf/tex/latex/espdx
```
Установить шаблоны для LyX:
```
git clone https://git.246060.ru:/f1x1t/lyx-layout-espdx.git ~/.lyx/layouts
```
Запустить LyX и в меню __Инструменты__ выбрать __Обновить конфигурацию__
и перезапустить программу.
Скачать [шаблон](files/espdx-template.lyx) для LyX, открыть файл
**espdx-template.lyx** и в меню выбрать __Документ / Настройки...__.
В появившемся окне нажать кнопку __Сохранить как параметры документа по умолчанию__.
Пример настройки:
![Класс документа](images/lyx-espdx/01.png)
![Модули](images/lyx-espdx/02.png)
![Шрифты](images/lyx-espdx/03.png)
![Макет текста](images/lyx-espdx/04.png)
![Макет страницы](images/lyx-espdx/05.png)
![Поля страницы](images/lyx-espdx/06.png)
![Язык](images/lyx-espdx/07.png)
![Нумерация и содержание](images/lyx-espdx/08.png)
![Библиография](images/lyx-espdx/09.png)
![Предметный указатель](images/lyx-espdx/10.png)
![Свойства PDF / Общие](images/lyx-espdx/11.png)
![Свойства PDF / Гиперссылки](images/lyx-espdx/12.png)
![Свойства PDF / Закладки](images/lyx-espdx/13.png)
![Параметры математики](images/lyx-espdx/14.png)
![Размещение плавающих объектов](images/lyx-espdx/15.png)
![Форматы](images/lyx-espdx/16.png)
![Преамбула LaTeX](images/lyx-espdx/17.png)

View File

@ -0,0 +1,13 @@
= LaTeX: защита команд
:title-separator: {sp}|
:category: LaTeX
:tags: LaTeX, текст,
Команда `\protect` используется для защиты инструкций внутри хрупких
команд. Например, для защиты команды переноса строки внутри команды
`section` нужно написать:
[source,latex]
----
\section{Первая строка\protect\\Вторая строка}
----

View File

@ -1,15 +0,0 @@
---
title: "LaTeX: защита команд"
category: LaTeX
tags: LaTeX, текст,
summary:
...
Команда `\protect` используется для защиты инструкций внутри
хрупких команд. Например, для защиты команды переноса строки
внутри команды `section` нужно написать:
```latex
\section{Первая строка\protect\\Вторая строка}
```

View File

@ -1,14 +1,12 @@
---
title: "LaTeX: лигатуры"
category: LaTeX
tags: LaTeX, шрифты,
summary:
...
= LaTeX: лигатуры
:title-separator: {sp}|
:category: LaTeX
:tags: LaTeX, шрифты,
Команды для запрета использования лигатур:
```latex
[source,latex]
----
\usepackage{microtype}
\DisableLigatures[f]{encoding = *, family = *}
```
----

View File

@ -0,0 +1,29 @@
= LyX: многостраничные таблицы
:title-separator: {sp}|
:category: LaTeX
:tags: LaTeX, текст, LyX, таблицы,
* Создать таблицу как минимум с четырьмя строками.
* Щёлкнуть правой кнопкой мыши на таблице, выбрать во всплывающем меню
*Длинная таблица*.
* Щёлкнуть правой кнопкой мыши на таблице, выбрать во всплывающем меню
*Настройки*.
* Установить курсор на первой строке таблицы, в окне настроек перейти на
вкладку *Длинная таблица*.
* Выбрать *Подпись* и *Первый заголовок*.
* Нажать *Применить*.
* Установить курсор на второй строке таблицы, в окне настроек перейти на
вкладку *Длинная таблица*.
* Выбрать *Подпись* и *Заголовок*.
* Нажать *Применить*.
* Установить курсор на третьей строке таблицы, в окне настроек перейти
на вкладку *Длинная таблица*.
* Выбрать *Заголовок* и *Первый заголовок*.
* Нажать *Применить*.
* Щёлкнуть правой кнопкой мыши на второй строке таблицы, выбрать в меню
*Подпись (Ненумерованный)*.
* На первой строке таблицы установить метку и ввести текст подписи к
таблице на начальной странице.
* На второй строке таблицы сформировать текст подписи к таблице, который
будет использоваться на последующих страницах.
* На третьей строке нужно сформировать заголовок таблицы.

View File

@ -1,32 +0,0 @@
---
title: "LyX: многостраничные таблицы"
category: LaTeX
tags: LaTeX, текст, LyX, таблицы,
summary:
...
- Создать таблицу как минимум с четырьмя строками.
- Щелкнуть правой кнопкой мыши на таблице, выбрать во всплывающем
меню **Длинная таблица**.
- Щелкнуть правой кнопкой мыши на таблице, выбрать во всплывающем
меню **Настройки**.
- Установить курсор на первой строке таблицы, в окне настроек перейти
на вкладку **Длинная таблица**.
- Выбрать **Подпись** и **Первый заголовок**.
- Нажать **Применить**.
- Установить курсор на второй строке таблицы, в окне настроек перейти
на вкладку **Длинная таблица**.
- Выбрать **Подпись** и **Заголовок**.
- Нажать **Применить**.
- Установить курсор на третьей строке таблицы, в окне настроек перейти
на вкладку **Длинная таблица**.
- Выбрать **Заголовок** и **Первый заколовок**.
- Нажать **Применить**.
- Щелкнуть правой кнопкой мыши на второй строке таблицы, выбрать в меню
**Подпись (Ненумерованный)**.
- На первой строке таблицы установить метку и ввести текст подписи к
таблице на начальной странице.
- На второй строке таблицы сформировать текст подписи к таблице,
который будет использоваться на последующих страницах.
- На третьей строке нужно сформировать заголовок таблицы.

View File

@ -0,0 +1,8 @@
= LaTeX: переносы строк
:title-separator: {sp}|
:category: LaTeX
:tags: LaTeX, текст,
Текст между командами `\sloppy` и `\fussy` или внутри блока
`\begin{sloppypar} ... \end{sloppypar}` будет переноситься сразу при
достижении края бокса.

View File

@ -1,11 +0,0 @@
---
title: "LaTeX: переносы строк"
category: LaTeX
tags: LaTeX, текст,
summary:
...
Текст между командами `\sloppy` и `\fussy` или внутри блока
`\begin{sloppypar} ... \end{sloppypar}` будет переноситься
сразу при достижении края бокса.

View File

@ -0,0 +1,20 @@
= LaTeX: русский язык в выходном PDF
:title-separator: {sp}|
:category: LaTeX
:tags: LaTeX, текст, PDF,
Данный метод используется только в LaTeX, в XeTeX (XeLaTeX) генерация
PDF работает изначально.
Для поиска в файле PDF и копирования текста с правильной кодировкой
нужно использовать пакет https://www.ctan.org/pkg/cmap[`cmap`]. Включать
использование пакета нужно как можно раньше, чтобы правильно
формировалась служебная информация и титульные листы.
[source,latex]
----
\usepackage{cmap}
----
Полезная http://s.arboreus.com/2007/07/pdf-latex.html[информация] о
выводе из LaTeX в PDF.

View File

@ -1,22 +0,0 @@
---
title: "LaTeX: русский язык в выходном PDF"
category: LaTeX
tags: LaTeX, текст, PDF,
summary:
...
Данный метод используется только в LaTeX, в XeTeX (XeLaTeX) генерация PDF
работает изначально.
Для поиска в файле PDF и копирования текста с правильной кодировкой
нужно использовать пакет [`cmap`](https://www.ctan.org/pkg/cmap).
Включать использование пакета нужно как можно раньше, чтобы правильно
формировалась служебная информация и титульные листы.
```latex
\usepackage{cmap}
```
Полезная [информация](http://s.arboreus.com/2007/07/pdf-latex.html)
о выводе из LaTeX в PDF.

View File

@ -1,26 +1,26 @@
---
title: "Astra: авторизация в PostgreSQL через PAM"
category: Linux
tags: Linux, Astra, postgresql, базы данных,
summary:
...
= Astra: авторизация в PostgreSQL через PAM
:title-separator: {sp}|
:category: Linux
:tags: Linux, Astra, postgresql, базы данных,
Для обеспечения авторизации пользователей через PAM системному
пользователю `postgres`, с правами которого выполняется сервер
базы данных, необходимо выдать права на чтение информации из базы
данных пользователей и сведений о мандатных метках и привилегиях:
пользователю `postgres`, с правами которого выполняется сервер базы
данных, необходимо выдать права на чтение информации из базы данных
пользователей и сведений о мандатных метках и привилегиях:
```sh
[source,sh]
----
usermod -a -G shadow postgres
setfacl -d -m u:postgres:r /etc/parsec/macdb
setfacl -R -m u:postgres:r /etc/parsec/macdb
setfacl -m u:postgres:rx /etc/parsec/macdb
```
----
Для обеспечения возможности авторизации пользователя `user`,
зарегистрированного в системе PAM, нужно выполнить команду
```sh
[source,sh]
----
usermac -c 0:0 -l 0:0 user
```
----

View File

@ -1,42 +1,46 @@
---
title: "CUPS: команды"
category: Linux
tags: Linux, печать, CUPS
...
= CUPS: команды
:title-separator: {sp}|
:category: Linux
:tags: Linux, печать, CUPS,
Текущее состояние принтера (см. также [lpstat](http://cheat.sh/lpstat)):
Текущее состояние принтера (см. также http://cheat.sh/lpstat[lpstat]):
```sh
[source,sh]
----
lpstat -h hostname -p printer_name
```
----
Возобновить работу принтера:
```sh
[source,sh]
----
lpadmin -h hostname -p printer_name -E
```
----
Печать (см. также [lp](http://cheat.sh/lp)):
Печать (см. также http://cheat.sh/lp[lp]):
```sh
[source,sh]
----
lp -h hostname -d printer_name file.pdf
```
----
Просмотр очереди:
```sh
[source,sh]
----
lpq -h hostname -p printer_name
```
----
Удаление задания job-id из очереди:
```sh
[source,sh]
----
lprm -h hostname -p printer_name job-id
```
----
Удаление всех заданий из очереди:
```sh
[source,sh]
----
lprm -h hostname -p printer_name -
```
----

View File

@ -1,12 +1,10 @@
---
title: "APT"
category: Linux
tags: linux, ubuntu, debian, apt,
summary:
...
= APT
:category: Linux
:tags: linux, ubuntu, debian, apt,
Запрет загрузки переводов описаний пакетов:
```sh
[source,sh]
----
echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/99translations
```
----

View File

@ -1,32 +1,36 @@
---
title: "GnuPG: шифрование файлов"
category: Linux
tags: Linux, GnuPG, безопасность
...
= GnuPG: шифрование файлов
:title-separator: {sp}|
:category: Linux
:tags: Linux, GnuPG, безопасность
Для шифрования файлов с использованием публичного ключа адресата можно выполнить команду:
Для шифрования файлов с использованием публичного ключа адресата можно
выполнить команду:
```sh
[source,sh]
----
tar cp files_list | pv | gpg -e --recipient user@domain.tld > archive.tar.gpg
```
----
По умолчанию во время шифрования данные сжимаются компрессорами `zip` или `gzip`,
поэтому сжимать данные до `gpg` не нужно. Можно отключить стандартный алгоритм сжатия и
использовать собственный компрессор, например `xz`:
По умолчанию во время шифрования данные сжимаются компрессорами `zip`
или `gzip`, поэтому сжимать данные до `gpg` не нужно. Можно отключить
стандартный алгоритм сжатия и использовать собственный компрессор,
например `xz`:
```sh
[source,sh]
----
tar cp files_list | pv | xz -9 | gpg -e --compress-algo none --recipient user@domain.tld > archive.tar.xz.gpg
```
----
Для шифрования с использованием пароля:
```sh
[source,sh]
----
tar cf files_list | pv | gpg -c > archive.tar.gpg
```
----
Для расшифровки нужно выполнить команду:
```sh
[source,sh]
----
gpg -d archive.tar.gpg --output archive.tar
```
----

View File

@ -0,0 +1,28 @@
= Прерывания GPE
:category: Linux
:tags: Linux, hardware, железо,
Неисправная аппаратура может генерировать большое количество прерываний,
что приводит к заметному ухудшению отзывчивости системы. Проверить
наличие подобной ситуации можно командой
[source,sh]
----
find /sys/firmware/acpi/interrupts | sort | while read i; do echo "$i:"; cat $i; done
----
Если в выводе будет присутствовать очень большое число, то значит
проявляется именно данная проблема. Для временного исправления можно
заблокировать прерывание, выполнив команду
[source,sh]
----
echo 0 > /sys/firmware/acpi/interrupts/gpeXX 2>/dev/null
----
где XX номер прерывания, для которого зафиксировано большое число
срабатываний. Для полного исправления проблемы нужно разбираться с
аппаратурой.
https://unix.stackexchange.com/questions/242013/disable-gpe-acpi-interrupts-on-boot[См.
также]

View File

@ -1,28 +0,0 @@
---
title: "Прерывания GPE"
category: Linux
tags: Linux, hardware, железо,
summary:
...
Неисправная аппаратура может генерировать большое количество прерываний,
что приводит к заметному ухудшению отзывчивости системы. Проверить
наличие подобной ситуации можно командой
```sh
find /sys/firmware/acpi/interrupts | sort | while read i; do echo "$i:"; cat $i; done
```
Если в выводе будет присутствовать очень большое число, то значит проявляется
именно данная проблема. Для временного исправления можно заблокировать прерывание,
выполнив команду
```sh
echo 0 > /sys/firmware/acpi/interrupts/gpeXX 2>/dev/null
```
где XX номер прерывания, для которого зафиксировано большое число срабатываний.
Для полного исправления проблемы нужно разбираться с аппаратурой.
[См. также](https://unix.stackexchange.com/questions/242013/disable-gpe-acpi-interrupts-on-boot)

View File

@ -0,0 +1,15 @@
= DNS в контейнере LXC
:category: Linux
:tags: lxc, контейнеры, ubuntu, linux, dns,
В системе Ubuntu 18.04 работающей внутри контейнера LXC по умолчанию не
работает разрешение имён. Чтобы использовать DNS-сервер `8.8.8.8`, нужно
внутри контейнера выполнить команды:
[source,sh]
----
sed -i 's/#DNS=/DNS=8.8.8.8/' /etc/systemd/resolved.conf
systemctl restart systemd-resolved
rm /etc/resolv.conf
ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
----

View File

@ -1,17 +0,0 @@
---
title: "DNS в контейнере LXC"
category: Linux
tags: lxc, контейнеры, ubuntu, linux, dns,
summary:
...
В системе Ubuntu 18.04 работающей внутри контейнера LXC по умолчанию
не работает разрешение имён. Чтобы использовать DNS-сервер `8.8.8.8`,
нужно внутри контейнера выполнить команды:
```sh
sed -i 's/#DNS=/DNS=8.8.8.8/' /etc/systemd/resolved.conf
systemctl restart systemd-resolved
rm /etc/resolv.conf
ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
```

View File

@ -1,28 +1,28 @@
---
title: "runit: система инициализации"
category: Linux
tags: Debian, Ubuntu, Linux, инициализация, runit,
summary:
...
= runit: система инициализации
:title-separator: {sp}|
:category: Linux
:tags: Debian, Ubuntu, Linux, инициализация, runit,
### Установка
== Установка
[runit](http://smarden.org/runit/) — это система инициализации со
http://smarden.org/runit/[runit] — это система инициализации со
встроенными средствами контроля за процессами.
Установка в Ubuntu:
```sh
[source,sh]
----
sudo apt-get install runit runit-systemd
```
----
### Запуск сервисов от непривилегированного пользователя
== Запуск сервисов от непривилегированного пользователя
Чтобы разрешить непривилегированному пользователю `user` управлять
собственной конфигурацией для runit, нужно с правами суперпользователя
выполнить:
```sh
[source,sh]
----
mkdir -p /etc/service/run-user/supervise
cat > /etc/service/run-user/run << EOF
#!/bin/sh
@ -31,17 +31,18 @@ exec 2>&1
exec chpst -u user runsvdir /home/user/sv
EOF
chmod +x /etc/service/run-user/run
```
----
В результате в каталоге `/home/user/sv` пользователь `user` сможет
создавать собственные правила управления сервисами.
### Пример сервиса
== Пример сервиса
Для запуска сервера Redis пользователем `user` нужно создать файл
конфигурации `/home/user/redis/etc/redis.conf`:
```
[source,text]
----
daemonize no
port 5079
tcp-backlog 128
@ -56,33 +57,36 @@ client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 4mb 1mb 60
client-output-buffer-limit pubsub 4mb 1mb 60
maxclients 50
```
----
Запускаемый сервер должен запускаться не в фоновом режиме, чтобы
runit мог контролировать его состояние.
Запускаемый сервер должен запускаться не в фоновом режиме, чтобы `runit`
мог контролировать его состояние.
Скрипт `/home/user/sv/redis/run`, который `runit` использует для
запуска процесса:
Скрипт `/home/user/sv/redis/run`, который `runit` использует для запуска
процесса:
```sh
#!/bin/sh
[source,sh]
----
#!/bin/sh -e
WORKDIR=/home/user/redis
cd "${WORKDIR}" || exit 1
exec 2>&1
exec redis-server etc/redis.conf
```
----
Журналирование выполняется с помощью входящей в состав пакета
runit программы `svlogd`. Скрипт для его запуска должен находиться
в подкаталоге `log` (`/home/user/sv/redis/log/run`):
Журналирование выполняется с помощью входящей в состав пакета runit
программы `svlogd`. Скрипт для его запуска должен находиться в
подкаталоге `log` (`/home/user/sv/redis/log/run`):
```sh
[source,sh]
----
#!/bin/sh -e
LOGDIR=/home/user/redis/log
mkdir -p "${LOGDIR}"
exec svlogd -tt "${LOGDIR}""
```
----

View File

@ -1,16 +1,14 @@
---
title: "Сервер времени NTP в локальной сети"
category: Linux
tags: Linux, NTP, время,
summary:
...
= Сервер времени NTP в локальной сети
:category: Linux
:tags: Linux, NTP, время,
Если в локальной сети необходимо синхронизировать время, не имея
авторитетного источника времени, то можно использовать локальные
часы сервера в качестве базовых. В этом случае файл настройки
`/etc/ntp.conf` на сервере `192.168.0.1` будет выглядеть так:
авторитетного источника времени, то можно использовать локальные часы
сервера в качестве базовых. В этом случае файл настройки `/etc/ntp.conf`
на сервере `192.168.0.1` будет выглядеть так:
```
[source,text]
----
driftfile /var/lib/ntp/ntp.drift
logfile /var/log/ntp.log
tinker panic 0
@ -19,11 +17,12 @@ server 127.127.1.0 minpoll 4 maxpoll 7
fudge 127.127.1.0 stratum 8
restrict 192.168.0.0 mask 255.255.255.0
restrict default nomodify notrap
```
----
Файл `/etc/ntp.conf` на клиенте из подсети `192.168.0.0/24` имеет вид:
```
[source,text]
----
driftfile /var/lib/ntp/ntp.drift
logfile /var/log/ntp.log
tinker panic 0
@ -32,5 +31,4 @@ server 127.127.1.0 minpoll 4 maxpoll 7
fudge 127.127.1.0 stratum 12
server 192.168.0.1 minpoll 4 maxpoll 7 iburst
restrict default nomodify nopeer
```
----

View File

@ -1,20 +1,19 @@
---
title: "Терминал rxvt-unicode"
category: Linux
tags: Linux, Xorg, rxvt, терминал,
summary:
...
= Терминал rxvt-unicode
:category: Linux
:tags: Linux, Xorg, rxvt, терминал,
Скачать скрипт для динамического изменения размера шрифта
```sh
[source,sh]
----
curl -fLo $HOME/.urxvt/ext/font-size --create-dirs \
https://raw.githubusercontent.com/majutsushi/urxvt-font-size/master/font-size
```
----
Добавить в файл `$HOME/.Xresources`:
```
[source,text]
----
URxvt.background: White
URxvt.foreground: Black
URxvt.saveLines: 8192
@ -40,5 +39,5 @@ URxvt.keysym.C-S-KP_Subtract: perl:font-size:decglobal
! Запрет печати
URxvt.print-pipe: "cat > /dev/null"
```
----

View File

@ -0,0 +1,9 @@
= Linux: полезные ссылки
:title-separator: {sp}|
:category: Linux
:tags: Linux, ссылки,
* https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html[Параметры
загрузки ядра]
* http://cheat.sh/[Примеры команд]
* https://m.opennet.ru/[Новости]

View File

@ -1,10 +0,0 @@
---
title: "Linux: полезные ссылки"
category: Linux
tags: Linux, ссылки,
...
* [Параметры загрузки ядра](https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html)
* [Примеры команд](http://cheat.sh/)
* [Новости](https://m.opennet.ru/)

31
wiki/Misc/Libgen.adoc Normal file
View File

@ -0,0 +1,31 @@
= Libgen: локальная база данных для Windows
:title-separator: {sp}|
:category: Windows
:tags: windows, libgen, библиотеки, книги,
Программа http://libruslib.ucoz.com/index/libgen_bibliotekar/0-5[LibGen
- Библиотекарь] позволяет просматривать локальную копию базы данных
сервера http://libgen.io/[Libgen]. Архив базы данных можно скачать
http://gen.lib.rus.ec/dbdumps/[здесь]. В архиве базы с именем вида
`libgen_YYYY-MM-DD.rar` содержится полная информация для полнотекстового
поиска по описаниям книг, а в архиве с именем вида
`libgen-compact_YYYY-MM-DD.rar` описания удалены.
Для обработки полного архива потребуется около 30 ГБ свободного
пространства. Последовательность действий:
* https://yadi.sk/d/j_ToPE7D3SHGN6[Скачать] и распаковать программу
Libgen.
* Скачать архив базы данных, распаковать его в каталог `upload` и
переименовать SQL-скрипт в `backup_ba.sql`.
* https://yadi.sk/d/psnuXFJM3SHGR8[Скачать] архив со скриптами для
преобразования базы данных и распаковать его в каталог `upload`.
* Запустить программу `libgen.exe`.
* Выбрать в меню menu:Databases[Update book database].
* Перечень настроек должен быть таким:
** [ ] Download from the Internet
** [ ] Unpack
** [x] Prepare for import to the database
* Нажать кнопку btn:[Start].
* После завершения работы нажать кнопку btn:[Done].
* Удалить из каталога `upload` файл `backup_ba1.sql`.

View File

@ -1,30 +0,0 @@
---
title: "Libgen: локальная база данных для Windows"
category: Windows
tags: windows, libgen, библиотеки, книги,
summary:
...
Программа [LibGen - Библиотекарь](http://libruslib.ucoz.com/index/libgen_bibliotekar/0-5)
позволяет просматривать локальную копию базы данных сервера [Libgen](http://libgen.io/).
Архив базы данных можно скачать [здесь](http://gen.lib.rus.ec/dbdumps/).
В архиве базы с именем вида `libgen_YYYY-MM-DD.rar` содержится полная информация
для полнотекстового поиска по описаниям книг, а в архиве с именем вида
`libgen-compact_YYYY-MM-DD.rar` описания удалены.
Для обработки полного архива потребуется около 25 Гб свободного пространства.
Последовательность действий:
1. [Скачать](https://yadi.sk/d/j_ToPE7D3SHGN6) и распаковать программу Libgen.
2. Скачать архив базы данных, распаковать его в каталог `upload`
и переименовать SQL-скрипт в `backup_ba.sql`.
3. [Скачать](https://yadi.sk/d/psnuXFJM3SHGR8) архив со скриптами для преобразования
базы данных и распаковать его в каталог `upload`.
4. Запустить программу `libgen.exe`.
5. Выбрать в меню **Databases | Update book database**.
6. Убрать галочки **Download from the Internet** и **Unpack** и поставить
**Prepare for import to the database**.
7. Нажать кнопку **Start**.
8. После завершения работы нажать кнопку **Done**.
9. Удалить из каталога `upload` файл `backup_ba1.sql`.

View File

@ -0,0 +1,22 @@
= Настройка Windows в O&O ShutUp10
:category: Misc
:tags: Windows, настройка, программы,
Программа https://www.oo-software.com/en/shutup10[O&O ShutUp10]
используется для быстрой настроки большого количества параметров
Windows{nbsp}10. Пример приведён ниже:
.Экран 1
image::oo-shutup/1.jpg[1]
.Экран 2
image::oo-shutup/2.jpg[2]
.Экран 3
image::oo-shutup/3.jpg[3]
.Экран 4
image::oo-shutup/4.jpg[4]
.Экран 5
image::oo-shutup/5.jpg[5]

View File

@ -1,22 +0,0 @@
---
title: "Настройка Windows в O&O ShutUp10"
category: Misc
tags: Windows, настройка, программы,
summary:
...
Программа [O&O ShutUp10](https://www.oo-software.com/en/shutup10)
используется для быстрой настроки большого количества параметров Windows 10.
Пример приведён ниже:
![1](images/oo-shutup/1.jpg)
![2](images/oo-shutup/2.jpg)
![3](images/oo-shutup/3.jpg)
![4](images/oo-shutup/4.jpg)
![5](images/oo-shutup/5.jpg)

View File

@ -1,38 +1,20 @@
---
title: "CMake: управление проектом"
category: Программирование
tags: программирование, cmake,
summary:
toc: yes
monofontoptions:
- Scale=0.6
...
= CMake: управление проектом
:title-separator: {sp}|
:category: Программирование
:tags: программирование, cmake,
:toc:
<style type="text/css" rel="stylesheet">
table {
table-layout: fixed;
}
thead th:nth-child(1) {
width: 30%;
}
thead th:nth-child(2) {
width: 70%;
}</style>
== Полезные ссылки
[TOC]
* https://github.com/onqtam/awesome-cmake[Каталог ссылок]
* https://cgold.readthedocs.io/en/latest/index.html[CGold: The
Hitchhikers Guide to the CMake]
### Полезные ссылки
* [Каталог ссылок](https://github.com/onqtam/awesome-cmake)
* [CGold: The Hitchhikers Guide to the CMake](https://cgold.readthedocs.io/en/latest/index.html)
### Структура каталогов проекта
== Структура каталогов проекта
Файлы проекта и результаты компиляции размещаются в каталогах:
```
....
└── cmex
├── _build
│ ├── Debug
@ -54,68 +36,85 @@ thead th:nth-child(2) {
│ └── lib
├── thirdparty
└── tools
```
....
Назначение каталогов приведено в таблице.
Каталог | Назначение
-------------------------|----------------------------------------------
`cmex/_build` | Результаты компиляции
`cmex/_build/Debug` | Результаты компиляции в режиме отладки
`cmex/_build/Release` | Результаты компиляции в режиме выпуска
`cmex/.git` | Репозиторий git
`cmex/cmake` | Файлы с дополнительными функциями для CMake
`cmex/cmake/cmlib` | Библиотека функций для CMake
`cmex/cmake/find` | Модули CMake для поиска внешних программ и библиотек
`cmex/cmake/etc` | Файлы настроек, используемые в CMake
`cmex/cmake/generators` | Генераторы проектов
`cmex/doc` | Документация для проекта
`cmake/files` | Каталог для дополнительных файлов
`cmake/files/etc` | Каталог для файлов настроек проекта
`cmake/files/share` | Каталог для неизменяемых файлов
`cmake/files/var` | Каталог для изменяемых файлов
`cmex/l10n` | Файлы переводов
`cmex/src` | Исходные тексты
`cmex/src/app` | Исходные тексты программ
`cmex/src/lib` | Исходные тексты библиотек
`cmex/thirdparty` | Исходные тексты сторонних проектов
`cmex/tools` | Дополнительные утилиты
[cols="1,3",options="header",]
|===
|Каталог |Назначение
|`cmex/_build` |Результаты компиляции
|`cmex/_build/Debug` |Результаты компиляции в режиме отладки
|`cmex/_build/Release` |Результаты компиляции в режиме выпуска
|`cmex/.git` |Репозиторий git
|`cmex/cmake` |Файлы с дополнительными функциями для CMake
|`cmex/cmake/cmlib` |Библиотека функций для CMake
|`cmex/cmake/find` |Модули CMake для поиска внешних программ и библиотек
|`cmex/cmake/etc` |Файлы настроек, используемые в CMake
|`cmex/cmake/generators` |Генераторы проектов
|`cmex/doc` |Документация для проекта
|`cmake/files` |Каталог для дополнительных файлов
|`cmake/files/etc` |Каталог для файлов настроек проекта
|`cmake/files/share` |Каталог для неизменяемых файлов
|`cmake/files/var` |Каталог для изменяемых файлов
|`cmex/l10n` |Файлы переводов
|`cmex/src` |Исходные тексты
|`cmex/src/app` |Исходные тексты программ
|`cmex/src/lib` |Исходные тексты библиотек
|`cmex/thirdparty` |Исходные тексты сторонних проектов
|`cmex/tools` |Дополнительные утилиты
|===
Каталог `_build` создаётся, чтобы избежать попадания получаемых во время
сборки файлов в иерархию основного проекта.
Запись результатов сборки проекта внутрь иерархии каталогов с исходными текстами
приводит к засорению формируемыми на этапе сборки файлами, которые затрудняют
разработку, поиск в оригинальных файлах и мешают ориентироваться в проекте.
При работе с несколькими типами сборки, например, отладка и выпуск, появляется
необходимость корректного полного удаления результатов предыдущего тип сборки.
сборки файлов в иерархию основного проекта. Запись результатов сборки
проекта внутрь иерархии каталогов с исходными текстами приводит к
засорению формируемыми на этапе сборки файлами, которые затрудняют
разработку, поиск в оригинальных файлах и мешают ориентироваться в
проекте. При работе с несколькими типами сборки, например, отладка и
выпуск, появляется необходимость корректного полного удаления
результатов предыдущего тип сборки.
== Начало проекта
### Начало проекта
Проект, в котором выполнены приведённые ниже действия, можно посмотреть
https://git.246060.ru/f1x1t/cmex[здесь] или сделать его копию командой:
[source,sh]
----
git clone --recursive https://git.246060.ru/f1x1t/cmex
----
В каталоге `cmex` нужно создать файл `CMakeLists.txt`:
```cmake
[source,cmake]
----
# Минимальная версия Cmake
cmake_minimum_required(VERSION 3.3)
cmake_policy(VERSION 3.0.2..3.7)
# Название и версия проекта и используемые языки программирования
project(cmex VERSION 0.2.0 LANGUAGES C CXX)
```
----
Значение версии следует формировать согласно правилам
[семантического версионирования](https://semver.org/lang/ru/).
https://semver.org/lang/ru/[семантического версионирования].
В каталог `cmake/cmlib` установить субмодуль CMLib, содержащий функции для CMake:
В каталоге `cmex` нужно инициализировать репозиторий и установить
подмодули, содержащие функции для CMake:
```
git submodule add ssh://git@gitlab-server/root/cmlib cmake/cmlib
```
[source,sh]
----
git init .
git submodule add https://git.246060.ru/f1x1t/cmlib cmake/cmlib
git submodule add https://git.246060.ru/f1x1t/cmake-find cmake/find
git submodule add https://git.246060.ru/f1x1t/cmake-generators cmake/generators
git submodule update --remote --init
----
и подключить в файле `CMakeLists.txt`:
```cmake
[source,cmake]
----
# В каталоге cmake/cmlib находятся файлы с библиотечными функциями
if(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/cmake/cmlib)
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/cmlib)
@ -125,19 +124,19 @@ endif()
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/find)
include(CMLibCommon)
```
----
В файле `cmake/etc/organization.txt` записать название
организации, которой принадлежит проект:
В файле `cmake/etc/organization.txt` записать название организации,
которой принадлежит проект:
```
....
ORG, Inc.
```
....
В файле `cmake/etc/cpack_ignore.txt` перечислить шаблоны
для исключения из архива, создаваемого целью `dist`. Например:
В файле `cmake/etc/cpack_ignore.txt` перечислить шаблоны для исключения
из архива, создаваемого целью `dist`. Например:
```
....
cmake/lib/.git$
.git$
files/var
@ -146,57 +145,59 @@ CMakeLists.txt.user
\\\\..*\\\\.bak$
\\\\..*\\\\.tmp$
\\\\..*\\\\.swp$
```
....
Чтобы проверить корректность файла `CMakeLists.txt`, нужно создать
каталог `_build` в каталоге `cmex`, перейти в него и выполнить команды:
Чтобы проверить корректность файла `CMakeLists.txt`, нужно создать каталог
`_build` в каталоге `cmex`, перейти в него и выполнить команды:
```sh
[source,sh]
----
cmake ..
make
```
----
### Поиск системных библиотек
== Поиск системных библиотек
Системные библиотеки можно искать с помощью программы `pkgconfig`,
которая хранит базу данных параметров, включающую пути к заголовочным
файлами и перечни библиотек, необходимых для компоновки.
Сначала производится наличие модуля `PkgConfig`, в котором определена
функция `pkg_check_modules`, которая и осуществляет поиск. Например,
для поиска библиотек `gsl`, `fftw3` и `udev` можно написать:
файлами и перечни библиотек, необходимых для компоновки. Сначала
производится наличие модуля `PkgConfig`, в котором определена функция
`pkg_check_modules`, которая и осуществляет поиск. Например, для поиска
библиотек `gsl`, `fftw3` и `udev` можно написать:
```cmake
[source,cmake]
----
# Поиск библиотек с помощью pkgconfig
find_package(PkgConfig)
pkg_check_modules(GSL REQUIRED gsl)
pkg_check_modules(FFTW3 REQUIRED fftw3)
pkg_check_modules(UDEV udev)
```
----
Если системная библиотека поставляется без файла описания для `pkgconfig`,
то для её поиска может быть написан специальный модуль для `CMake`,
который вызывается функцией `find_package`. Кроме того функция `find_package`
может возвращать дополнительные значения, например, пути к исполняемым файлам.
Если системная библиотека поставляется без файла описания для
`pkgconfig`, то для её поиска может быть написан специальный модуль для
`CMake`, который вызывается функцией `find_package`. Кроме того функция
`find_package` может возвращать дополнительные значения, например, пути
к исполняемым файлам.
```cmake
[source,cmake]
----
# Поиск с помощью функции find_package
find_package(LibXml2)
find_package(CURL)
```
----
Если для библиотеки нет модуля, выполняющего её поиск, то можно
произвести поиск с помощью функции `find_library`. Например,
```cmake
[source,cmake]
----
# Поиск библиотеки с помощью функции find_library
find_library(MATHGL mgl PATHS /usr/lib /usr/lib/x86_64-linux-gnu)
find_library(MATHGLQT5 mgl-qt5 PATHS /usr/lib /usr/lib/x86_64-linux-gnu)
```
----
### Автоматически генерируемый заголовочный файл
== Автоматически генерируемый заголовочный файл
На этапе конфигурирования проекта можно создать файл, в который будут
записаны параметры, полученные на данной стадии. В библиотеке CMLib
@ -204,24 +205,26 @@ find_library(MATHGLQT5 mgl-qt5 PATHS /usr/lib /usr/lib/x86_64-linux-gnu)
`${CMAKE_BUILD_DIR}/include/config.hpp`, в который записывается
информация о имени и версии проекта, дате и типе сборки.
```cmake
[source,cmake]
----
# Автоматически генерируемый заголовочный файл
cmlib_config_hpp_generate()
```
----
== Базовая библиотека
### Базовая библиотека
В файле `cmex/CMakeLists.txt` должна быть строка, включающая поиск файла
`CMakeLists.txt` в подкаталоге `src/lib`:
В файле `cmex/CMakeLists.txt` должна быть строка, включающая
поиск файла `CMakeLists.txt` в подкаталоге `src/lib`:
```cmake
[source,cmake]
----
add_subdirectory(src/libcmex)
```
----
В каталоге `cmex/src/libcmex` нужно создать файл `cmex.hpp`:
```cpp
[source,cpp]
----
#ifndef LIBCMEX_CMEX_HPP_
#define LIBCMEX_CMEX_HPP_
@ -230,21 +233,23 @@ add_subdirectory(src/libcmex)
int32_t cmex_init(int32_t i);
#endif // LIBCMEX_CMEX_HPP_
```
----
файл `cmex.cpp`:
```cpp
[source,cpp]
----
#include "cmex.hpp"
int32_t cmex_init(int32_t i = 0) {
return i;
}
```
----
и файл `CMakeLists.txt`:
```cmake
[source,cmake]
----
# Название основной цели и имя библиотеки в текущем каталоге
set(current_target cmex)
@ -274,21 +279,22 @@ if(BUILD_SHARED_LIBS)
endif()
install(FILES ${CMAKE_BINARY_DIR}/include/config.hpp ${current_target_headers}
COMPONENT headers DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${current_target})
```
----
== Базовое приложение
### Базовое приложение
В файле `cmex/CMakeLists.txt` должна быть строка, включающая поиск файла
`CMakeLists.txt` в подкаталоге `src/cmex`:
В файле `cmex/CMakeLists.txt` должна быть строка, включающая поиск файла `CMakeLists.txt`
в подкаталоге `src/cmex`:
```cmake
[source,cmake]
----
add_subdirectory(src/cmex)
```
----
В каталоге `cmex/src/cmex` нужно создать файл `main.cpp`:
```cpp
[source,cpp]
----
#include "compiler_features.hpp"
#include "config.hpp"
@ -303,12 +309,12 @@ int main(int argc, char **argv) {
std::cout << cmex_init(4) << std::endl; // Функция из внутренней библиотеки
return 0;
}
```
----
и файл `CMakeLists.txt`:
```cmake
[source,cmake]
----
# Название основной цели в текущем каталоге
set(current_target cmex_app)
@ -343,15 +349,15 @@ target_link_libraries(${current_target} cmex_static)
# Правила для установки
install(TARGETS ${current_target} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
```
----
### Подключение внешнего проекта
== Подключение внешнего проекта
В каталоге `cmex/thirdparty` нужно создать каталог `cmext` с проектом,
состоящим из файлов `cmext.hpp`:
```c
[source,c]
----
#ifndef CMEXT_CMEXT_HPP_
#define CMEXT_CMEXT_HPP_
@ -360,21 +366,23 @@ install(TARGETS ${current_target} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
int32_t cmext_init(int32_t i);
#endif
```
----
`cmext.cpp`:
```c
[source,c]
----
#include "cmext.hpp"
int32_t cmext_init(int32_t i = 0) {
return i;
}
```
----
и `CMakeLists.txt`:
```cmake
[source,cmake]
----
cmake_minimum_required(VERSION 3.3)
project(cmext)
@ -382,54 +390,60 @@ include(GNUInstallDirs)
add_library(cmext cmext.cpp)
install(TARGETS cmext ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES cmext.hpp COMPONENT headers DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_PROJECT_NAME})
```
----
В файле `cmex/CMakeLists.txt` нужно подключить стандартный модуль
`ExternalProject` и описать правила для его загрузки, настройки,
компиляции и установки для сопряжения с текущим проектом:
```cmake
[source,cmake]
----
# Подключение внешних проектов
include(ExternalProject)
ExternalProject_Add(cmext
EXCLUDE_FROM_ALL TRUE
SOURCE_DIR ${CMAKE_SOURCE_DIR}/thirdparty/libcmext
SOURCE_DIR ${CMAKE_SOURCE_DIR}/thirdparty/cmext
INSTALL_DIR ${CMAKE_BINARY_DIR}
DOWNLOAD_COMMAND ""
BUILD_BYPRODUCTS <INSTALL_DIR>/lib/libcmext.a
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_BUILD_TYPE=Release
)
```
----
Вызовы этих функций нужно сделать до функций `add_subdirectories`,
чтобы в подключенных подкаталогах можно было использовать цель `cmext`
для определения зависимостей.
Вызовы этих функций нужно сделать до функций `add_subdirectories`, чтобы
в подключенных подкаталогах можно было использовать цель `cmext` для
определения зависимостей.
В файле `cmex/src/cmex/CMakeLists.txt` нужно подключить внешний проект `cmext`:
В файле `cmex/src/cmex/CMakeLists.txt` нужно подключить внешний проект
`cmext`:
```cmake
[source,cmake]
----
# Зависимость от библиотеки из внешнего проекта проекта
add_dependencies(${current_target} cmext)
```
----
```cmake
[source,cmake]
----
# Добавление каталога, в который устанавливаются заголовочные файлы от внешнего
# проекта cmext, к списку путей для поиска заголовочных файлов
target_include_directories(${current_target} PUBLIC
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/include/cmext>)
```
----
```cmake
[source,cmake]
----
# Библиотека из внешнего проекта cmext
target_link_libraries(${current_target} ${CMAKE_BINARY_DIR}/lib/libcmext.a)
```
----
Для проверки работоспособности в файле `cmex/src/cmex/main.cpp` нужно вызвать
функцию `cmext_init` из библиотеки, предоставляемой внешним проектом.
Например:
Для проверки работоспособности в файле `cmex/src/cmex/main.cpp` нужно
вызвать функцию `cmext_init` из библиотеки, предоставляемой внешним
проектом. Например:
```cpp
[source,cpp]
----
#include "compiler_features.hpp"
#include "config.hpp"
@ -458,41 +472,42 @@ int main(int argc, char **argv) {
return 0;
}
```
----
== Qt5
### Qt5
Для поиска необходимых компонентов Qt5 нужно в файл
`cmex/CMakeLists.txt` добавить строки:
Для поиска необходимых компонентов Qt5 нужно в файл `cmex/CMakeLists.txt`
добавить строки:
```cmake
[source,cmake]
----
find_package(Qt5 COMPONENTS Core Network Gui Widgets DBus Concurrent Sql REQUIRED)
```
----
Библиотека CMLib автоматически подключает вызов препроцессора `moc`
и компилятора ресурсов `rcc`, если цель использует модуль `Core`, и
Библиотека CMLib автоматически подключает вызов препроцессора `moc` и
компилятора ресурсов `rcc`, если цель использует модуль `Core`, и
вызывает компилятор файлов описания интерфейса, если цель использует
модуль `Widgets`.
### Консольное приложение
== Консольное приложение
В файл `cmex/src/cmex/CMakeLists.txt` добавить строки:
```cmake
[source,cmake]
----
# Qt5
qt_translation(TARGET ${current_target} TS_DIR ${CMAKE_SOURCE_DIR}/l10n LANGUAGES ru_RU)
target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS})
target_compile_options(${current_target} PUBLIC "${Qt5Core_EXECUTABLE_COMPILE_FLAGS}")
target_link_libraries(${current_target} Qt5::Core)
```
----
Для проверки работоспособности подключения Qt5 файл `cmex/src/cmex/main.cpp`
нужно заменить на:
Для проверки работоспособности подключения Qt5 файл
`cmex/src/cmex/main.cpp` нужно заменить на:
```cpp
[source,cpp]
----
#include "compiler_features.hpp"
#include "config.hpp"
@ -529,28 +544,30 @@ int main(int argc, char **argv) {
return 0;
}
```
----
После сборки проекта в каталоге `cmex/l10n` появится файл `cmex_app_ru_RU.ts`,
в котором нужно отредактировать переводы с помощью программы `linguist`.
После сохранения переводов проект нужно пересобрать, файл переводов в
скопилированном виде будет встроен в исполняемый файл `cmex`, а доступ
к нему будет осуществляться с помощью кода:
После сборки проекта в каталоге `cmex/l10n` появится файл
`cmex_app_ru_RU.ts`, в котором нужно отредактировать переводы с помощью
программы `linguist`. После сохранения переводов проект нужно
пересобрать, файл переводов в скомпилированном виде будет встроен в
исполняемый файл `cmex`, а доступ к нему будет осуществляться с помощью
кода:
```cpp
[source,cpp]
----
if (translator.load(QLocale(), "cmex_app", QLatin1String("_"), QLatin1String(":/qm")))
{
app.installTranslator(&translator);
}
```
----
== Графическое приложение
### Графическое приложение
Для создания минимального графического приложения нужно создать файл
описания интерфейса `cmex/src/cmex/my_main_window.ui`:
Для создания минимального графического приложения нужно создать
файл описания интерфейса `cmex/src/cmex/my_main_window.ui`:
```xml
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MyMainWindow</class>
@ -571,11 +588,12 @@ int main(int argc, char **argv) {
<resources/>
<connections/>
</ui>
```
----
заголовочный файл `cmex/src/cmex/my_main_window.hpp`:
```cpp
[source,cpp]
----
#ifndef CMEX_MY_MAIN_WINDOW_HPP_
#define CMEX_MY_MAIN_WINDOW_HPP_
@ -590,11 +608,13 @@ class MyMainWindow : public QWidget, private Ui::MyMainWindow {
};
#endif /* CMEX_MY_MAIN_WINDOW_HPP_ */
```
----
и файл с реализацией конструктора и деструктора `cmex/src/cmex/my_main_window.cpp`:
и файл с реализацией конструктора и деструктора
`cmex/src/cmex/my_main_window.cpp`:
```cpp
[source,cpp]
----
#include "my_main_window.hpp"
MyMainWindow::MyMainWindow(QWidget* parent) {
@ -604,12 +624,13 @@ MyMainWindow::MyMainWindow(QWidget* parent) {
MyMainWindow::~MyMainWindow() {
}
```
----
Для отображения графического окна нужно заменить файл
`cmex/src/cmex/main.cpp` на:
```cpp
[source,cpp]
----
#include "compiler_features.hpp"
#include "config.hpp"
@ -651,12 +672,13 @@ int main(int argc, char **argv) {
mmw->show();
return app.exec();
}
```
----
В файле `cmex/src/cmex/CMakeLists.txt` добавить новые файлы
к списку файлов, используемых для компиляции:
В файле `cmex/src/cmex/CMakeLists.txt` добавить новые файлы к списку
файлов, используемых для компиляции:
```cmake
[source,cmake]
----
set(current_target_sources
main.cpp
my_main_window.cpp
@ -665,51 +687,51 @@ set(current_target_sources
set(current_target_uis
my_main_window.ui
)
```
----
```cmake
[source,cmake]
----
# Цель для создания исполняемого файла
add_executable(${current_target} ${current_target_sources} ${current_target_uis})
```
----
и добавить строки для подключения графических библиотек Qt5
и соответствующих им заголовочных файлов:
и добавить строки для подключения графических библиотек Qt5 и
соответствующих им заголовочных файлов:
```cmake
[source,cmake]
----
target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Gui_INCLUDE_DIRS})
target_include_directories(${current_target} SYSTEM PUBLIC ${Qt5Widgets_INCLUDE_DIRS})
target_link_libraries(${current_target} Qt5::Gui)
target_link_libraries(${current_target} Qt5::Widgets)
```
----
Во время сборки проекта в файл переводов `cmex/l10n/cmex_app_ru_RU.ts`
будут добавлены повые строки, их нужно перевести с помощью `linguist`
и снова скомпилировать проект.
будут добавлены новые строки, их нужно перевести с помощью `linguist` и
снова скомпилировать проект.
### Удаление установленных файлов
== Удаление установленных файлов
В библиотеку CMLib добавлена цель `uninstall`, позволяющая удалить
файлы, перечисленные в файле `${CMAKE_BUILD_DIR}/install_manifest.txt`.
== Архивирование проекта
### Архивирование проекта
Стандартный модуль `CPack` осуществляет архивирование проекта. В файле
`cproj/cmake/etc/cpack_ignore.txt` определён список типовых масок файлов
для исключения из архива:
Стандарный модуль `CPack` осуществляет архивирование проекта. В файле
`cproj/cmake/etc/cpack_ignore.txt` определён список типовых масок файлов для
исключения из архива:
```
....
.git$
files/var
CMakeLists.txt.user
~$
\\\\..*\\\\.bak$
\\\\..*\\\\.tmp$
\\\\..*\\\\.bak$
\\\\..*\\\\.swp$
```
\\\\..*\\\\.o$
....
По умолчанию цель для упаковки проекта называется `package_source`.
В библиотеке CMLib определены значения основных параметров, а также
По умолчанию цель для упаковки проекта называется `package_source`. В
библиотеке CMLib определены значения основных параметров, а также
дополнительная цель `dist`.

View File

@ -0,0 +1,39 @@
= Intel Parallel Studio: установка в образ для чтения
:title-separator: {sp}|
:category: Linux/Программы
:tags: Linux, Intel, компилятор, C++,
Для установки и использования Intel Parallel Studio в сжатом образе
доступном только для чтения необходимо:
[arabic]
. Скачать
https://software.intel.com/en-us/parallel-studio-xe[дистрибутив] и
распаковать его.
. Скачать файл link:files/parallel-studio/silent.cfg[`silent.cfg`] и
скопировать его в полученный каталог.
. Если есть файл лицензии `parallel_studio.lic`, скопировать его в
каталог `/opt/intel/licenses`.
. Добавить полномочия для сбора статистики:
[source,sh]
----
sudo setcap cap_sys_ptrace=eip /opt/intel/vtune_amplifier/bin64/amplxe-cl
sudo setcap cap_sys_ptrace=eip /opt/intel/vtune_amplifier/bin64/amplxe-perf
----
[arabic, start=5]
. От суперпользователя установить в каталог `/opt/intel` командой
`sudo ./install.sh -s silent.cfg`.
. Создать образ
`mksquashfs /opt/intel/* /home/user/intel.sfs -comp xz -Xbcj x86 -all-root -b 512K`
. Удалить содержимое каталога `/opt/intel`.
. Примонтировать образ:
`mount -t squashfs /home/user/intel.sfs /opt/intel`
. Добавить в файл `/home/user/.bashrc` строки:
[source,sh]
----
source /opt/intel/bin/compilervars.sh intel64
source /opt/intel/vtune_amplifier/amplxe-vars.sh
----

View File

@ -1,22 +0,0 @@
---
title: "Intel Parallel Studio: установка в образ для чтения"
category: Linux/Программы
tags: Linux, Intel, компилятор, C++
summary:
...
Для установки и использования Intel Parallel Studio
в сжатом образе доступном только для чтения необходимо:
1. Скачать [дистрибутив](https://software.intel.com/en-us/parallel-studio-xe) и распаковать его.
2. Скачать файл [`silent.cfg`](files/parallel-studio/silent.cfg) и скопировать его в полученный каталог.
3. Если есть файл лицензии `parallel_studio.lic`, скопировать его в каталог `/opt/intel/licenses`.
4. От суперпользователя установить в каталог `/opt/intel` командой `sudo ./install.sh -s silent.cfg`.
5. Создать образ `mksquashfs /opt/intel/* /home/user/intel.sfs -comp xz -Xbcj x86 -all-root -b 512K`
6. Удалить содержимое каталога `/opt/intel`.
7. Подмонтировать образ: `mount -t squashfs /home/user/intel.sfs /opt/intel`
8. Добавить в файл `/home/user/.bashrc` строки:
```sh
source /opt/intel/bin/compilervars.sh intel64
source /opt/intel/vtune_amplifier/amplxe-vars.sh
```

View File

@ -1,59 +1,62 @@
---
title: "PVS-Studio"
category: Программирование
tags: программирование, C, C++, отладка,
summary:
toc: yes
...
= PVS-Studio
:category: Программирование
:tags: программирование, C, C++, отладка,
[TOC]
:toc:
### Информация и лицензия
== Информация и лицензия
[PVS-Studio](https://www.viva64.com/ru/pvs-studio/) — это инструмент для
статического анализа исходного кода программ, написанных на языках С, C++.
https://www.viva64.com/ru/pvs-studio/[PVS-Studio] — это инструмент для
статического анализа исходного кода программ, написанных на языках С,
C++.
Для использования в Linux нужно чтобы в каталоге `~/.config/PVS-Studio`
находился лицензионный ключ или в начале исходных файлов с расширениями
`*.c`, `*.cpp`, `*.cxx` и т.п. [присутствовали строки](https://www.viva64.com/ru/b/0457/)
`*.c`, `*.cpp`, `*.cxx` и т.п.
https://www.viva64.com/ru/b/0457/[присутствовали строки]
```
....
// This is an independent project of an individual developer. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
```
....
### Настройка и компиляция проекта
== Настройка и компиляция проекта
Полное руководство для работы в Linux находится
[здесь](https://www.viva64.com/ru/m/0036/), а ниже приведён список типовых команд.
https://www.viva64.com/ru/m/0036/[здесь], а ниже приведён список типовых
команд.
Настройка проекта для CMake:
```sh
[source,sh]
----
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=On <src-tree-root>
```
----
Сборка проекта с помощью `make`:
```sh
[source,sh]
----
pvs-studio-analyzer trace -- make -j$(nproc)
```
----
Настройка и сборка проекта с использованием Ninja:
```sh
[source,sh]
----
cmake -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=On <src-tree-root>
ninja -t compdb
```
----
### Анализ проекта
== Анализ проекта
Для анализа проектов используется утилита `pvs-studio-analyzer`. По умолчанию
включены только диагностики общего назначения (General Analysis, GA).
Включить дополнительные правила можно с помощью опции `-a`:
Для анализа проектов используется утилита `pvs-studio-analyzer`. По
умолчанию включены только диагностики общего назначения (General
Analysis, GA). Включить дополнительные правила можно с помощью опции
`-a`:
```
....
-a [MODE], --analysis-mode [MODE]
MODE defines the type of warnings:
1 - 64-bit errors;
@ -64,45 +67,50 @@ ninja -t compdb
32 - MISRA.
Modes can be combined by adding the values
Default: 4
```
....
Выбор типов предупреждений осуществляется на основе побитовой маски из
приведенных выше типов. Чтобы выполнить анализ, исключив проверки MISRA,
приведённых выше типов. Чтобы выполнить анализ, исключив проверки MISRA,
нужно выполнить
```sh
[source,sh]
----
pvs-studio-analyzer analyze -a 29 -j$(nproc) -o pvs.log
```
----
Составление отчёта для просмотра в Qt Creator:
```sh
[source,sh]
----
plog-converter -t tasklist -o pvs.tasks pvs.log
```
----
При составлении отчёта уровень детализации можно изменять с помощью ключа
`-a` (`--analyzer`), который производит фильтрацию предупреждений согласно
маске, которая имеет вид `MessageType:MessageLevels`, где `MessageType`
может принимать один из следующих типов: `GA`, `OP`, `64`, `CS`, `MISRA`,
а `MessageLevels` может принимать значения от `1` до `3`.
При составлении отчёта уровень детализации можно изменять с помощью
ключа `-a` (`--analyzer`), который производит фильтрацию предупреждений
согласно маске, которая имеет вид `MessageType:MessageLevels`, где
`MessageType` может принимать один из следующих типов: `GA`, `OP`, `64`,
`CS`, `MISRA`, а `MessageLevels` может принимать значения от `1` до `3`.
Возможна комбинация разных масок через `;`. Например, при составлении
отчёта для просмотра в формате HTML можно повысить уровень детализации:
```sh
[source,sh]
----
plog-converter -t fullhtml -a "GA:1,2,3;64:1;OP:1,2;CS:1,2" -o html pvs.log
```
----
Составление отчёта для редактора Vim:
```sh
[source,sh]
----
plog-converter -a "GA:1,2" -t errorfile -o pvs.err pvs.log
```
----
Для просмотра отчёта в редакторе Vim нужно открыть файл `pvs.err` и выполнить команды:
Для просмотра отчёта в редакторе Vim нужно открыть файл `pvs.err` и
выполнить команды:
```vim
[source,vim]
----
:set makeprg=cat\ % " выбор программы для компиляции в текущей сессии
:silent make " имитация сборки
:cw " открытие результатов в нижнем окне
```
----

View File

@ -0,0 +1,36 @@
= Подбор ключей компиляции GCC
:category: Программирование
:tags: программирование, C, C++, отладка, оптимизация,
Подбор ключей компиляции основан на измерениях характеристик во время
выполнения программы. На первом этапе создаётся исполняемый файл
`program`, в который включается информация для профилировки. Ключ
`-fprofile-generate=data/pgo` указывает, что нужно собирать информацию и
сохранять в каталог `data/pgo`. Компиляцию следует выполнять в
последовательном режиме.
[source,sh]
----
env CXXFLAGS='-fprofile-generate=data/pgo' cmake .. -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles"
make -j1
----
После компиляцию программу следует выполнить, придерживаясь типичного
сценария использования.
[source,sh]
----
./program
----
Скомпилировать программу с использованием полученной статистики. Для
многопоточной программы следует указать флаг `-fprofile-correction`,
чтобы скорректировать данные, которые могут неустойчивыми из-за
пропусков обновлений счётчиков. Компиляцию следует выполнять в
последовательном режиме.
[source,sh]
----
env CXXFLAGS='-fprofile-use=data/pgo -fprofile-correction' cmake .. -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles"
make -j1
----

View File

@ -1,35 +0,0 @@
---
title: "Подбор ключей компиляции GCC"
category: Программирование
tags: программирование, C, C++, отладка, оптимизация,
summary:
...
Подбор ключей компиляции основан на измерениях характеристик во
время выполнения программы. На первом этапе создаётся исполняемый
файл `program`, в который включается информация для профилировки.
Ключ `-fprofile-generate=data/pgo` указывает, что нужно собирать
информацию и сохранять в каталог `data/pgo`. Компиляцию следует
выполнять в последовательном режиме.
```sh
env CXXFLAGS='-fprofile-generate=data/pgo' cmake .. -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles"
make -j1
```
После компиляцию программу следует выполнить, придерживаясь
типичного сценария использования.
```sh
./program
```
Скомпилировать программу с использованием полученной статистики.
Для многопоточной программы следует указать флаг `-fprofile-correction`,
чтобы скорректировать данные, которые могут неустойчивыми из-за пропусков
обновлений счётчиков. Компиляцию следует выполнять в последовательном режиме.
```sh
env CXXFLAGS='-fprofile-use=data/pgo -fprofile-correction' cmake .. -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles"
make -j1
```

View File

@ -0,0 +1,77 @@
= Профилирование кода
:category: Программирование
:tags: программирование, отладка, производительность, профилирование, gprof,
== Общее описание
Чтобы профилировать приложения, компилируемые http://gcc.gnu.org[GCC],
необходимо добавлять флаг `-fno-omit-frame-pointer` и, желательно, `-g`.
== quickstack
Утилита для отслеживания стеков вызовов функций
https://github.com/yoshinorim/quickstack[quicktrack]. Пример
использования:
[source,sh]
----
quickstack -f -p $(pidof application)
----
== perf
Утилита профилирования для ядра Linux (находится в дереве его исходных
текстов в каталоге `tools/perf`).
[source,sh]
----
perf record --call-graph dwarf -- ./application
perf report -g graph --no-children
----
Полезные ссылки:
* https://perf.wiki.kernel.org/index.php/Main_Page[Официальная страница]
* https://stackoverflow.com/questions/1777556/alternatives-to-gprof/10958510#10958510[Примеры]
* http://www.brendangregg.com/perf.html[Примеры]
== oprofile
[source,sh]
----
opcontrol --setup --vmlinux=/boot/vmlinux-`uname -r`
----
== Systemtap
https://eax.me/systemtap/[Установка и простые примеры использования
SystemTap]
== Valgrind
https://eax.me/valgrind/[Хорошая статья] об использовании Valgrind для
поиска утечек, а также о взаимодействии с GDB.
В версии 3.15 добавление инструмент профилирования кучи DHAT (Dynamic
Heap Analysis Tool), позволяющий отследить все запросы на распределения
памяти в куче и выявить утечки ресурсов, места излишне большой
активности при работе с кучей, неиспользованные выделения памяти,
краткосрочные выделения и неэффективное размещение данных в куче.
[source,sh]
----
valgrind --tool=dhat ./application
----
== gperftools
== Разное
* https://eax.me/c-cpp-profiling/[Профилирование кода на C/C++ в Linux и
FreeBSD]
* http://gernotklingler.com/blog/gprof-valgrind-gperftools-evaluation-tools-application-level-cpu-profiling-linux/[Примеры]
== Графическое отображение
* http://www.brendangregg.com/flamegraphs.html[Flame Graphs]
* https://github.com/jrfonseca/gprof2dot[gprof2dot]

View File

@ -1,79 +0,0 @@
---
title: "Профилирование кода"
category: Программирование
tags: программирование, отладка, производительность, профилирование, gprof,
summary:
...
## Общее описание
Чтобы профилировать приложения, компилируемые [GCC](http://gcc.gnu.org),
необходимо добавлять флаг `-fno-omit-frame-pointer` и, желательно, `-g`.
## quickstack
Утилита для отслеживания стеков вызовов функций [quicktrack](https://github.com/yoshinorim/quickstack).
Пример использования:
```sh
quickstack -f -p $(pidof application)
```
## perf
Утилита профилирования для ядра Linux (находится в дереве его исходных текстов
в каталоге `tools/perf`).
```sh
perf record --call-graph dwarf -- ./application
perf report -g graph --no-children
```
Полезные ссылки:
* [Официальная страница](https://perf.wiki.kernel.org/index.php/Main_Page)
* [Примеры](https://stackoverflow.com/questions/1777556/alternatives-to-gprof/10958510#10958510)
* [Примеры](http://www.brendangregg.com/perf.html)
## oprofile
```sh
opcontrol --setup --vmlinux=/boot/vmlinux-`uname -r`
```
## Systemtap
[Установка и простые примеры использования SystemTap](https://eax.me/systemtap/)
## Valgrind
[Хорошая статья](https://eax.me/valgrind/) об использовании Valgrind для поиска
утечек, а также о взаимодействии с GDB.
В версии 3.15 добавление инструмент профилирования кучи DHAT (Dynamic
Heap Analysis Tool), позволяющий отследить все запросы на распределения
памяти в куче и выявить утечки ресурсов, места излишне большой активности
при работе с кучей, неиспользованные выделения памяти, краткосрочные
выделения и неэффективное размещение данных в куче.
```sh
valgrind --tool=dhat ./application
```
## gperftools
## Разное
* [Профилирование кода на C/C++ в Linux и FreeBSD](https://eax.me/c-cpp-profiling/)
* [Примеры](http://gernotklingler.com/blog/gprof-valgrind-gperftools-evaluation-tools-application-level-cpu-profiling-linux/)
## Графическое отображение
* [Flame Graphs](http://www.brendangregg.com/flamegraphs.html)
* [gprof2dot](https://github.com/jrfonseca/gprof2dot)

View File

@ -1,33 +1,33 @@
---
title: "Статический анализ кода"
category: Программирование
tags: программирование, отладка, cppcheck, iwyu, clang-tidy, cpplint, clazy,
summary:
...
= Статический анализ кода
:category: Программирование
:tags: программирование, отладка, cppcheck, iwyu, clang-tidy, cpplint, clazy,
## Общее описание
== Общее описание
Ниже приведены утилиты для проверки кода на C++ и примеры их настройки и использования
совместно с [CMake](https://cmake.org/).
Ниже приведены утилиты для проверки кода на C++ и примеры их настройки и
использования совместно с https://cmake.org/[CMake].
### [clang-tidy](http://clang.llvm.org/extra/clang-tidy/)
=== http://clang.llvm.org/extra/clang-tidy/[clang-tidy]
Установка:
```sh
[source,sh]
----
sudo apt-get install clang-tidy-6.0
```
----
Использование:
```sh
[source,sh]
----
cmake "-DCMAKE_CXX_CLANG_TIDY=/usr/bin/clang-tidy-6.0" path/to/source
```
----
В каталоге проекта нужно создать файл `.clang-tidy` в формате YAML со списком
выполняемых проверок. Например:
В каталоге проекта нужно создать файл `.clang-tidy` в формате YAML со
списком выполняемых проверок. Например:
```yaml
[source,yaml]
----
---
Checks: '-*,
clang-diagnostic-*,
@ -42,91 +42,97 @@ CheckOptions:
- key: readability-identifier-naming.ClassMemberCase
value: camelBack
...
```
----
Пример файла `.clang-tidy`, в котором перечислены все правила для проверки
именования идентификаторов приведён [здесь](https://git.246060.ru/f1x1t/clang-tidy-readability-identifier-naming).
Пример файла `.clang-tidy`, в котором перечислены все правила для
проверки именования идентификаторов приведён
https://git.246060.ru/f1x1t/clang-tidy-readability-identifier-naming[здесь].
### CppCheck
=== CppCheck
Установка:
```sh
[source,sh]
----
sudo apt-get install cppcheck
```
----
Использование:
```sh
[source,sh]
----
cmake "-DCMAKE_CXX_CPPCHECK=/usr/bin/cppcheck;--std=c++11" path/to/source
```
----
This will run /usr/bin/cppcheck;std=c++11″ source=/path/to/source/file.cxx on each c++ file in the project being built.
This will run /usr/bin/cppcheck;std=c++11″
source=/path/to/source/file.cxx on each c++ file in the project being
built.
### CppLint
=== CppLint
Установка:
```sh
[source,sh]
----
sudo apt-get install python3-cpplint
```
----
Использование:
```sh
[source,sh]
----
cmake "-DCMAKE_CXX_CPPLINT=/usr/bin/cpplint;--linelength=79" path/to/source
```
----
```sh
[source,sh]
----
make -j24 2>&1 1>/dev/null | ../cpplint2tasks.pl > 222.tasks
```
----
This will run /usr/local/bin/cpplint linelength=79 on each c++ file in the project being built.
This will run /usr/local/bin/cpplint linelength=79 on each c++ file in
the project being built.
### IWYU
=== IWYU
Установка:
```sh
[source,sh]
----
sudo apt-get install iwyu
```
----
Использование:
```sh
[source,sh]
----
cmake "-DCMAKE_CXX_INCLUDE_WHAT_YOU_USE=/usr/bin/iwyu;--transitive_includes_only" ..
```
----
This will run /usr/bin/iwyu transitive_includes_only on each c++ file
in the project being built.
This will run /usr/bin/iwyu transitive_includes_only on each c++ file in the project being built.
=== LWYU
### LWYU
```sh
[source,sh]
----
cmake -DCMAKE_LINK_WHAT_YOU_USE=TRUE ..
```
### Clazy
----
=== Clazy
Установка:
```sh
[source,sh]
----
sudo apt-get install clazy clang-6.0
```
----
Использование:
```sh
[source,sh]
----
CLAZY_CHECKS=level2 cmake -DCMAKE_CXX_COMPILER=clazy ..
CLANGXX=clang++-6.0 make
```
### PVS-Studio
----
=== PVS-Studio

View File

@ -0,0 +1,49 @@
= Построение профиля местности в Gis
:category: Картография
:tags: картография, qgis, sxf, shp, gdal,
[arabic]
. В главном меню QGis *Слой* — *Добавить слой* — *Добавить векторный
слой* выбрать и открыть файл с векторным слоем, например, `map.sxf`.
. Среди слоёв выбрать слой с рельефом местности и типом геометрии
`LineString`.
image:qgis-heights/1.png[Слои карты]
[arabic, start=3]
. На панели *Панель слоёв* правой кнопкой мыши щёлкнуть на слое,
содержащем данные о высотах, и выбрать *Фильтр…*.
. Построить выражение выбирающие только данные с высотами, например,
`"CLNAME" ILIKE '%ГОРИЗОНТАЛИ ОСНОВ%'` и нажить *OK*.
. На панели *Панель слоёв* правой кнопкой мыши щёлкнуть на слое,
содержащем данные о высотах, и выбрать *Сохранить как…*. Появившийся
новый слой *heights* следует удалить.
. В появившемся диалоговом окне выбрать имя выходного файла, например,
`heights`.
image:qgis-heights/2.png[Имя выходного файла]
[arabic, start=7]
. В каталоге `/home/a/work/map` выполнить команду, которая в файле
`heights.shp` из слоя `heights` берёт данные о высотах из поля `SC_4` и
генерирует матрицу высот размером 2000 на 2000 в формате BMP. Настойки
алгоритма построения матрицы можно изменять с помощью параметра `-a`:
[source,sh]
----
gdal_grid -a invdist:power=3.0:smoothing=1.0 -outsize 2000 2000 -of BMP -ot Byte -zfield SC_4 -l heights heights.shp heights.bmp
----
[arabic, start=8]
. После построения матрицы её можно импортировать в QGis как растровый
слой, для этого в главном меню QGis *Слой* — *Добавить слой* — *Добавить
растровый слой* нужно выбрать и открыть файл `heights.bmp`. В результате
на панели *Панель слоёв* появится растровый слой *heights*.
. С помощью модуля Profile Tool можно построить профиль местности. В
главном меню нужно выбрать *Модуль* — *Profile Tool* — *Terrain
profile*.
. На панели *Панель слоёв* нужно перенести растровый слой *heights* в
конец списка, выделить его и на панели *Profile Tool* нажать *Add
Layer*. После этого на карте можно строить профили местности.
image:qgis-heights/3.png[Матрица высот]

View File

@ -1,51 +0,0 @@
---
title: "Построение профиля местности в QGis"
category: Картография
tags: картография, qgis, sxf, shp, gdal,
summary:
...
1) В главном меню QGis **Слой****Добавить слой** — **Добавить векторный слой**
выбрать и открыть файл с векторным слоем, например, `map.sxf`.
2) Среди слоёв выбрать слой с рельефом местности и типом геометрии `LineString`.
![Слои карты](images/qgis-heights/1.png)
3) На панели **Панель слоёв** правой кнопкой мыши щелкнуть на слое,
содержащем данные о высотах, и выбрать **Фильтр...**.
4) Построить выражение выбирающие только данные с высотами, например,
`"CLNAME" ILIKE '%ГОРИЗОНТАЛИ ОСНОВ%'` и нажить **OK**.
5) На панели **Панель слоёв** правой кнопкой мыши щелкнуть на слое,
содержащем данные о высотах, и выбрать **Сохранить как...**. Появившийся
новый слой **heights** следует удалить.
6) В появившемся диалоговом окне выбрать имя выходного файла, например, `heights`.
![Имя выходного файла](images/qgis-heights/2.png)
7) В каталоге `/home/a/work/map` выполнить команду, которая в файле
`heights.shp` из слоя `heights` берёт данные о высотах из поля `SC_4`
и генерирует матрицу высот размером 2000 на 2000 в формате BMP.
Настойки алгоритма посторения матрицы можно изменять с помощью параметра `-a`:
```sh
gdal_grid -a invdist:power=3.0:smoothing=1.0 -outsize 2000 2000 -of BMP -ot Byte -zfield SC_4 -l heights heights.shp heights.bmp
```
8) После построения матрицы её можно импортировать в QGis как растровый
слой, для этого в главном меню QGis **Слой****Добавить слой**
**Добавить растровый слой** нужно выбрать и открыть файл `heights.bmp`.
В результате на панели **Панель слоёв** появится растровый слой **heights**.
9) С помощью модуля Profile Tool можно построить профиль местности. В главном
меню нужно выбрать **Модуль****Profile Tool****Terrain profile**.
10) На панели **Панель слоёв** нужно перенести растровый слой **heights**
в конец списка, выделить его и на панели **Profile Tool** нажать **Add Layer**.
После этого на карте можно строить профили местности.
![Матрица высот](images/qgis-heights/3.png)

View File

@ -0,0 +1 @@
{"checksum":"81886ef1b8d31cdb2b865473bbeb2cf9","width":671,"height":550}

View File

@ -0,0 +1 @@
{"checksum":"e76d88ee3db613b3f806d8c773281fdc","width":685,"height":363}

View File

@ -0,0 +1,30 @@
= Git: автоматическое сохранение в репозиторий
:title-separator: {sp}|
:category: Программирование
:tags: программирование, git,
Скрипт https://github.com/elnull/gitwatch[gitwatch] позволяет
отслеживать изменения в каталоге с помощью программы `inotifywait` и
фиксировать их в репозиторий. Для работы скрипта необходимо установить
пакет `inotify-tools`. Если нужно следить за каталогом `/home/user/dir`
и записывать историю изменений в `/home/user/repo/dir`, то нужно
инициализировать репозиторий:
[source,sh]
----
git init --bare /home/user/repo/dir
----
добавить шаблоны исключаемых файлов:
[source,sh]
----
printf '*.[oa]\n*.swp\n*~\n/.git' >> /home/user/repo/dir/info/exclude
----
и запустить скрипт:
[source,sh]
----
./gitwatch.sh -g /home/user/repo/dir /home/user/dir
----

View File

@ -1,27 +0,0 @@
---
title: "Git: автоматическое сохранение в репозиторий"
category: Программирование
tags: программирование, git,
...
Скрипт [gitwatch](https://github.com/elnull/gitwatch) позволяет отслеживать
изменения в каталоге с помощью программы `inotifywait` и фиксировать их в
репозиторий. Для работы скрипта необходимо установить пакет `inotify-tools`.
Если нужно следить за каталогом `/home/user/dir` и записывать историю
изменений в `/home/user/repo/dir`, то нужно инициализировать репозиторий:
```sh
git init --bare /home/user/repo/dir
```
добавить шаблоны исключаемых файлов:
```sh
printf '*.[oa]\n*.swp\n*~\n/.git' >> /home/user/repo/dir/info/exclude
```
и запустить скрипт:
```sh
./gitwatch.sh -g /home/user/repo/dir /home/user/dir
```

View File

@ -1,20 +1,17 @@
---
title: "Git: замена адреса подмодуля"
category: Программирование
tags: программирование, git,
monofontoptions:
- Scale=0.7
...
= Git: замена адреса подмодуля
:title-separator: {sp}|
:category: Программирование
:tags: программирование, git,
Если у подмодуля, находящегося в каталоге `thirdparty/example` нужно
заменить адрес синхронизации и имя используемой ветки, то в каталоге
с файлом `.gitmodules`, в котором содержится информация об этом подмодуле,
заменить адрес синхронизации и имя используемой ветки, то в каталоге с
файлом `.gitmodules`, в котором содержится информация об этом подмодуле,
нужно выполнить команды:
```sh
[source,sh]
----
git config --file=.gitmodules submodule.thirdparty/example.url https://github.com/username/ABC.git
git config --file=.gitmodules submodule.thirdparty/example.branch new-branch-name
git submodule sync --recursive
git submodule update --init --recursive --remote
```
----

View File

@ -0,0 +1,301 @@
= Git: основные команды
:title-separator: {sp}|
:category: Программирование
:tags: программирование, git
:toc:
== Ссылки
* https://githowto.com/ru/changes_not_files[GitHowTo]
* https://git-scm.com/book/ru/v2[ProGit]
* https://github.com/maxliscia/git-pocket[Git Pocket Guide]
== Установка
В Debian/Ubuntu:
[source,sh]
----
sudo apt-get install git
----
== Термины
[width="100%",cols="18%,20%,62%",options="header",]
|===
|Термин |Англ |Определение
|Рабочий каталог |working tree, working directory |Набор файлов в
текущем каталоге
|Репозиторий |repository, repo |Контейнер, хранящий историю изменений
файлов проекта
|Индекс |index, staging area |Область между рабочим каталогом и
репозиторием, в котором осуществляется подготовка к фиксации
|SHA-1 |SHA-1 |Уникальный идентификатор, отражающий информацию об
истории
|Ветка |branch |Именованная последовательность в истории изменений
|Фиксация (коммит) |commit |Набор файлов, записанных в историю
одновременно
|`HEAD` |`HEAD` |Имя ссылки на последнюю фиксацию в текущей ветке
|Метка |tag |Именованная ссылка на некоторую фиксацию в истории
|===
== Состояния
Файлы в рабочем каталоге могут отслеживаться системой контроля версий
(tracked) или нет (untracked). Отслеживаемые файлы, которые на диаграмме
обозначены зелёным фоном, могут быть неизменёнными (unmodified),
изменёнными (modified) или подготовленными к фиксации (indexed).
[.text-center]
.Состояния
[plantuml]
----
@startuml
participant untracked as "Неотслеживамые\n(untracked)"
box "Отслеживаемые"
participant staged as "Подготовленные к фиксации\n(indexed)" #55FF55
participant unmodified as "Неизменённые\n(unmodified)" #99FF99
participant modified as "Изменённые\n(modified)" #77FF77
end box
untracked -> staged : git add
staged -> unmodified : git commit
unmodified -> modified : редактирование
modified -> staged : git add
modified -> untracked: git rm --cached
unmodified -> untracked: git rm --cached
staged -> untracked: git rm --cached
@enduml
----
Основные команды, осуществляющие взаимодействие между рабочим каталогом,
индексом, локальным и удалённым репозиторием, приведены на диаграмме
ниже.
[.text-center]
.Команды
[plantuml]
----
@startuml
participant workspace as "Рабочий каталог\n(working dir)"
participant index as "Индекс\n(index)" #77FF77
participant local as "Локальный репозиторий\n(local repository)" #FF7777
participant remote as "Удалённый репозиторий\n(remote repository)" #7777FF
workspace -> local : git commit -a
workspace -> index : git add (-u)
index -> local : git commit
local -> remote : git push
== Обновление с сервера ==
remote -> workspace : git pull (rebase)
remote -> local : fetch
== Откат изменений ==
local -[#red]> workspace : git checkout HEAD
index -[#red]> workspace : git checkout
== Сравнение ==
local -[#blue]> workspace : git diff HEAD
index -[#blue]> workspace : git diff
@enduml
----
== Настройка
[width="100%",cols="15%,35%,50%",options="header",]
|===
|Команда |Ключи |Описание
|`git config` |`--global user.name "John Doe"` |Имя текущего
пользователя
|`git config` |`--global user.email "mail@example.com"` |Почта текущего
пользователя
|`git config` |`--list` |Вывод текущей конфигурации
|`git config` |`--global --list` |Вывод глобальной конфигурации
|===
== Инициализация
[width="100%",cols="15%,35%,50%",options="header",]
|===
|Команда |Ключи |Описание
|`git init` |`<dir>` |Создать пустой репозиторий в каталоге `<dir>`
|`git clone` |`<giturl>` `<dir>` |Создать в каталоге `<dir>` копию
репозитория, находящегося по адресу `<giturl>`
|`git clone` |`--recursive <giturl>` `<dir>` |Создать в каталоге `<dir>`
копию репозитория, находящегося по адресу `<giturl>`, с учётом
подмодулей
|===
== Подмодули
[width="100%",cols="15%,25%,60%",options="header",]
|===
|Команда |Ключи |Описание
|`git submodule` |`add <giturl> <dir>` |Добавить в каталог `<dir>`
текущего репозитория подмодуль, находящийся по адресу `<giturl>`
|`git submodule` |`update --recursive --remote` |Обновить подмодули
|`git submodule` |`sync --recursive` |Заменить адреса подмодулей на
указанные в файле `.gitmodules`
|===
Удаление подмодуля:
[source,sh]
----
git submodule deinit <path/to/submodule>
git rm <path/to/submodule>
----
== Фиксация
[width="100%",cols="15%,25%,60%",options="header",]
|===
|Команда |Ключи |Описание
|`git add` |`<filename>` |Подготовить файл `<filename>` к фиксации
|`git commit` | |Зафиксировать подготовленные файлы
|`git commit` |`-a` |Зафиксировать все отслеживаемые файлы, которые были
изменены
|===
== Удаление
[width="100%",cols="20%,20%,60%",options="header",]
|===
|Команда |Ключи |Описание
|`git rm` |`<filename>` |Удалить файл из индекса и рабочего каталога
|`git rm` |`-f <filename>` |Принудительное удаление файла
|`git rm` |`--cached <filename>` |Удаление файла из проекта, но не из
рабочего каталога
|===
== Информация
[cols=",,",options="header",]
|===
|Команда |Ключи |Описание
|`git status` |`-s` |Вывод информации о рабочем каталоге в краткой форме
|`git log` |`--oneline` |Вывод журнала изменений в краткой форме
|`git ls-files` | |Вывод списка отслеживаемых и подготовленных файлов
|===
== Удалённый репозиторий
[width="100%",cols="20%,20%,60%",options="header",]
|===
|Команда |Ключи |Описание
|`git remote` |`-v` |Список адресов удалённых репозиториев
|`git branch` |`-r` |Список веток в удалённых репозиториях
|`git remote` |`add <name> <url>` |Создать ссылку `<name>` на удалённый
репозиторий, находящийся по адресу `<url>`
|`git remote` |`rename <old> <new>` |Переименовать ссылку `<old>` на
`<new>`
|`git remote` |`rm <name>` |Удалить ссылку `<name>`
|===
* Обращение к удалённому репозиторию осуществляется по ссылке,
создаваемой командой `git remote`
* Команда `git clone` автоматически создаёт ссылку `origin`
== Отправка изменений
[width="100%",cols="20%,20%,60%",options="header",]
|===
|Команда |Ключи |Описание
|`git push` |`<remote> <branch>` |Отправить ветку `<branch>` в удалённый
репозиторий `<remote>`
|`git push` |`<remote> --all` |Отправить все ветки в удалённый
репозиторий `<remote>`
|`git push` |`--d <remote> <branch>` |Удалить ветку `<branch>` из
удалённого репозитория `<remote>`
|===
== Получение изменений
[width="100%",cols="20%,20%,60%",options="header",]
|===
|Команда |Ключи |Описание
|`git fetch` |`<remote>` |Получить изменения из всех веток репозитория
`<remote>`, но не выполнять слияние
|`git fetch` |`<remote> <branch>` |Получить изменения из ветки
`<branch>` репозитория `<remote>`, но не выполнять слияние
|`git merge` |`<remote>/<branch>` |Выполнить слияние с веткой `<branch>`
репозитория `<remote>`
|`git pull` |`<remote>` |Получение и слияние
|===
== Ветки
[cols=",,",options="header",]
|===
|Команда |Ключи |Описание
|`git branch` |`-a` |Список локальных и удалённых веток
|`git branch` | |Список локальных веток
|`git branch` |`<branch>` |Создать ветку `<branch>`
|`git checkout` |`<sha-1>` |Перейти к фиксации с идентификатором
`<sha-1>`
|`git branch` |`-m <old> <new>` |Переименовать ветку `<old>` в `<new>`
|`git merge` |`<branch>` |Слить изменения из ветки `<branch>` в текущую
ветку
|`git branch` |`-d <branch>` |Удалить ветку `<branch>`
|===
== Сравнение
[width="100%",cols="20%,20%,60%",options="header",]
|===
|Команда |Ключи |Описание
|`git diff` | |Сравнить рабочий каталог и индекс
|`git diff` |`-cached` |Сравнить индекс и последнюю фиксацию
|`git diff` |`HEAD` |Сравнить последнюю фиксацию и рабочий каталог
|`git diff` |`--stat` |Краткий вывод результатов
|`git diff` |`<sha-1> <sha-1>` |Сравнить две точки с указанными
идентификаторами
|`git diff` |`<dir>` `<file>` |Сравнивать только указанный каталог
`<dir>` или файл `<file>`
|`git difftool` | |Отобразить результаты сравнения в программе,
определяемой переменной `diff.tool`
|===

View File

@ -1,221 +0,0 @@
---
title: "Git: основные команды"
category: Программирование
tags: программирование, git
monofontoptions:
- Scale=0.8
...
<style type="text/css" rel="stylesheet">
table { table-layout: fixed;}
</style>
## Ссылки
* [GitHowTo](https://githowto.com/ru/changes_not_files)
* [ProGit](https://git-scm.com/book/ru/v2)
* [Git Pocket Guide](https://github.com/maxliscia/git-pocket)
## Установка
В Debian/Ubuntu:
```sh
sudo apt-get install git
```
## Термины
| Термин | Англ | Определение |
| ------ | ------ | ----------------------- |
| Рабочий каталог | working tree, working directory | Набор файлов в текущем каталоге |
| Репозиторий | repository, repo | Контейнер, хранящий историю изменений файлов проекта |
| Индекс | index, staging area | Область между рабочим каталогом и репозиторием, в которой осуществляется подготовка к фиксации |
| SHA-1 | SHA-1 | Уникальный идентификатор, отражающий информацию об истории |
| Ветка | branch | Именованная последовательность в истории изменений |
| Фиксация (коммит) | commit | Набор файлов, записанных в историю одновременно |
| `HEAD` | `HEAD` | Имя ссылки на последнюю фиксацию в текущей ветке |
| Метка | tag | Именованная ссылка на некоторую фиксацию в истории |
## Состояния
Файлы в рабочем каталоге могут отслеживаться системой контроля версий
(tracked) или нет (untracked). Отслеживаемые файлы, которые на диаграмме
обозначены зелёным фоном, могут быть неизменёнными (unmodified),
изменёнными (modified) или подготовленными к фиксации (indexed).
```plantuml
@startuml
participant untracked as "Неотслеживамые\n(untracked)"
box "Отслеживаемые"
participant staged as "Подготовленные к фиксации\n(indexed)" #55FF55
participant unmodified as "Неизменённые\n(unmodified)" #99FF99
participant modified as "Изменённые\n(modified)" #77FF77
end box
untracked -> staged : git add
staged -> unmodified : git commit
unmodified -> modified : редактирование
modified -> staged : git add
modified -> untracked: git rm --cached
unmodified -> untracked: git rm --cached
staged -> untracked: git rm --cached
@enduml
```
Основные команды, осуществляющие взаимодействие между рабочим каталогом,
индексом, локальным и удалённым репозиторием, приведены на диаграмме ниже.
```plantuml
@startuml
participant workspace as "Рабочий каталог\n(working dir)"
participant index as "Индекс\n(index)" #77FF77
participant local as "Локальный репозиторий\n(local repository)" #FF7777
participant remote as "Удалённый репозиторий\n(remote repository)" #7777FF
workspace -> local : git commit -a
workspace -> index : git add (-u)
index -> local : git commit
local -> remote : git push
== Обновление с сервера ==
remote -> workspace : git pull (rebase)
remote -> local : fetch
== Откат изменений ==
local -[#red]> workspace : git checkout HEAD
index -[#red]> workspace : git checkout
== Сравнение ==
local -[#blue]> workspace : git diff HEAD
index -[#blue]> workspace : git diff
@enduml
```
## Настройка
| Команда | Ключи | Описание |
| ---- | ---------- | ------------ |
| `git config` | `--global user.name "John Doe"` | Имя текущего пользователя |
| `git config` | `--global user.email "mail@example.com"` | Почта текущего пользователя |
| `git config` | `--list` | Вывод текущей конфигурации |
| `git config` | `--global --list` | Вывод глобальной конфигурации |
## Инициализация
| Команда | Ключи | Описание |
| ---- | ------ | ------------ |
| `git init` | `<dir>` | Создать пустой репозиторий в каталоге `<dir>` |
| `git clone` | `<giturl>` `<dir>` | Создать в каталоге `<dir>` копию репозитория, находящегося по адресу `<giturl>` |
| `git clone` | `--recursive <giturl>` `<dir>` | Создать в каталоге `<dir>` копию репозитория, находящегося по адресу `<giturl>`, с учётом подмодулей |
## Подмодули
| Команда | Ключи | Описание |
| ---- | ------ | ------------ |
| `git submodule` | `add <giturl> <dir>` | Добавить в каталог `<dir>` текущего рапозитория подмодуль, находящийся по адресу `<giturl>` |
| `git submodule` | `update --recursive --remote` | Обновить подмодули |
| `git submodule` | `sync --recursive` | Заменить адреса подмодулей на указанные в файле `.gitmodules` |
Удаление подмодуля:
```sh
git submodule deinit <path/to/submodule>
git rm <path/to/submodule>
```
## Фиксация
| Команда | Ключи | Описание |
| ---- | ---- | ------------ |
| `git add` | `<filename>` | Подготовить файл `<filename>` к фиксации |
| `git commit` | | Зафиксировать подготовленные файлы |
| `git commit` | `-a` | Зафиксировать все отслеживаемые файлы, которые были изменены |
## Удаление
| Команда | Ключи | Описание |
| ---- | ---- | ------------ |
| `git rm` | `<filename>` | Удалить файл из индекса и рабочего каталога |
| `git rm` | `-f <filename>` | Принудительное удаление файла |
| `git rm` | `--cached <filename>` | Удаление файла из проекта, но не из рабочего каталога |
## Информация
| Команда | Ключи | Описание |
| ---- | ---- | ------------ |
| `git status` | `-s` | Вывод информации о рабочем каталоге в краткой форме |
| `git log` | `--oneline` | Вывод журнала изменений в краткой форме |
| `git ls-files` | | Вывод списка отслеживаемых и подготовленных файлов |
## Удалённый репозиторий
| Команда | Ключи | Описание |
| ---- | ---- | ------------ |
| `git remote` | `-v` | Список адресов удалённых репозиториев |
| `git branch` | `-r` | Список веток в удалённых репозиториях |
| `git remote` | `add <name> <url>` | Создать ссылку `<name>` на удалённый репозиторий, находящийся по адресу `<url>` |
| `git remote` | `rename <old> <new>` | Переименовать ссылку `<old>` на `<new>` |
| `git remote` | `rm <name>` | Удалить ссылку `<name>` |
* Обращение к удалённому репозиторию осуществляется по ссылке, создаваемой командой `git remote`
* Команда `git clone` автоматически создаёт ссылку `origin`
## Отправка изменений
| Команда | Ключи | Описание |
| ---- | ---- | ------------ |
| `git push` | `<remote> <branch>` | Отправить ветку `<branch>` в удалённый репозиторий `<remote>` |
| `git push` | `<remote> --all` | Отправить все ветки в удалённый репозиторий `<remote>` |
| `git push` | `--d <remote> <branch>` | Удалить ветку `<branch>` из удалённого репозитория `<remote>` |
## Получение изменений
| Команда | Ключи | Описание |
| ---- | ---- | ------------ |
| `git fetch` | `<remote>` | Получить изменения из всех веток репозитория `<remote>`, но не выполнять слияние |
| `git fetch` | `<remote> <branch>` | Получить изменения из ветки `<branch>` репозитория `<remote>`, но не выполнять слияние |
| `git merge` | `<remote>/<branch>` | Выполнить слияние с веткой `<branch>` репозитория `<remote>` |
| `git pull` | `<remote>` | Получение и слияние |
## Ветки
| Команда | Ключи | Описание |
| ---- | ---- | ------------ |
| `git branch` | `-a` | Список локальных и удалённых веток |
| `git branch` | | Список локальных веток |
| `git branch` | `<branch>` | Создать ветку `<branch>` |
| `git checkout` | `<sha-1>` | Перейти к фиксации с идентификатором `<sha-1>` |
| `git branch` | `-m <old> <new>` | Переименовать ветку `<old>` в `<new>` |
| `git merge` | `<branch>` | Слить изменения из ветки `<branch>` в текущую ветку |
| `git branch` | `-d <branch>` | Удалить ветку `<branch>` |
## Сравнение
| Команда | Ключи | Описание |
| ---- | ---- | ------------ |
| `git diff` | | Сравнить рабочий каталог и индекс |
| `git diff` | `-cached` | Сравнить индекс и последнюю фиксацию |
| `git diff` | `HEAD` | Сравнить последнюю фиксацию и рабочий каталог |
| `git diff` | `--stat` | Краткий вывод результатов |
| `git diff` | `<sha-1> <sha-1>` | Сравнить две точки с указанными индетификаторами |
| `git diff` | `<dir> | <file>` | Сравнивать только укзанный каталог `<dir>` или файл `<file>` |
| `git difftool` | | Отобразить результаты сравнения в программе, определяемой переменной `diff.tool` |

View File

@ -0,0 +1,12 @@
= Git: распаковка объекта
:title-separator: {sp}|
:category: Программирование
:tags: программирование, git,
:toc:
В случае повреждения репозитория можно восстановить отдельные объекты,
которые сохраняются в формате zlib. Пример команды:
....
perl -MCompress::Zlib -e 'undef $/; print uncompress(<>)' < 1234567890abcdef1234567890abcdef012345 > file
....

View File

@ -1,14 +0,0 @@
---
title: "Git: распаковка объекта"
category: Программирование
tags: программирование, git,
monofontoptions:
- Scale=0.7
...
В случае повреждения репозитория можно восстановить отдельные
объекты, которые сохраняются в формате zlib. Пример команды:
```
perl -MCompress::Zlib -e 'undef $/; print uncompress(<>)' < 1234567890abcdef1234567890abcdef012345 > file
```

View File

@ -1,26 +1,27 @@
---
title: "Git: репозиторий на переносном устройстве"
category: Программирование
tags: программирование, git,
...
= Git: репозиторий на переносном устройстве
:title-separator: {sp}|
:category: Программирование
:tags: программирование, git,
Создание репозитория для нового проекта:
```sh
[source,sh]
----
ln -s /media/user/usbdisk/git /home/user/work/usbdisk/git
git --bare init /home/user/work/usbdisk/git/project.git
cd /home/user/work/projects
git clone /home/user/work/usbdisk/git/project.git
cd project
git remote set-url usb file:///home/user/work/usbdisk/git/project.git/
```
----
Добавление нового удалённого репозитория к существующему проекту:
```sh
[source,sh]
----
ln -s /media/user/usbdisk/git /home/user/work/usbdisk/git
git --bare init /home/user/work/usbdisk/git/project.git
cd /home/user/work/projects/project
git remote add usb file:///home/user/work/usbdisk/git/project.git
git push --set-upstream usb master
```
----

View File

@ -0,0 +1,30 @@
= Git: частичная копия репозитория
:title-separator: {sp}|
:category: Программирование
:tags: программирование, git,
Если проект очень большой, а следить нужно только за малой его частью,
можно создать частичную копию репозитория. Допустим, по адресу
`git://localhost/project.git` находится большой проект, в котором
интересует только последнее состояние каталогов `src/driver` и
`include/driver`. Сначала нужно создать пустой репозиторий и подготовить
его для получения только необходимых файлов:
[source,sh]
----
git init project
cd project
git remote add origin git://localhost/project.git
git config core.sparsecheckout true
echo "src/driver/*" >> .git/info/sparse-checkout
echo "include/driver/*" >> .git/info/sparse-checkout
----
После этого можно получать частичную копию проекта, а, добавив ключ
`--depth=1`, указать, что синхронизироваться должно только текущее
состояние файлов без учёта истории.
[source,sh]
----
git pull --depth=1 origin master
----

View File

@ -1,31 +0,0 @@
---
title: "Git: частичная копия репозитория"
category: Программирование
tags: программирование, git,
summary:
...
Если проект очень большой, а следить нужно только за малой
его частью, можно создать частичную копию репозитория.
Допустим, по адресу `git://localhost/project.git` находится
большой проект, в котором интересует только последнее
состояние каталогов `src/driver` и `include/driver`.
Сначала нужно создать пустой репозиторий и подготовить его
для получения только необходимых файлов:
```sh
git init project
cd project
git remote add origin git://localhost/project.git
git config core.sparsecheckout true
echo "src/driver/*" >> .git/info/sparse-checkout
echo "include/driver/*" >> .git/info/sparse-checkout
```
После этого можно получать частичную копию проекта,
а, добавив ключ `--depth=1`, указать, что синхронизироваться
должно только текущее состояние файлов без учёта истории.
```sh
git pull --depth=1 origin master
```

View File

@ -0,0 +1,39 @@
= GitLab: выполнение по расписанию
:title-separator: {sp}|
:category: Программирование
:tags: программирование, gitlab, git,
После помещения изменений (push) на сервер следует выполнять только
задачи, не требующие много ресурсов. Ресурсоёмкие задачи можно отложить
на время минимальной нагрузки сервера. Для этого нужно:
* в секциях файла `.gitlab-ci.yml`, запускающих задачи с высокой
нагрузкой, добавить
[source,yaml]
----
only:
- schedules
----
подробнее это описано
https://docs.gitlab.com/ee/ci/yaml/#only-and-except-simplified[здесь]
* в веб-интерфейсе в меню *CI/CD* / *Расписания* добавить *Новое
расписание* и назначить исполнение задачи на время, когда нагрузка на
сервер минимальна.
Для пропуска запланированной задачи в исполняемый скрипт нужно добавить
проверку условия запуска. Например, чтобы отменить запуск компиляции,
если за последний день (86400 секунд) не было изменений, можно оформить
`.gitlab-ci.yml` примерно так:
[source,yaml]
----
nightly-job:
only:
- schedules
script:
- "[ $(($(date +%s)-$(git log -1 --date=format:%s --format=%cd))) -gt 86400 ] && exit 0"
- make
----

View File

@ -1,36 +0,0 @@
---
title: "GitLab: выполнение по расписанию"
category: Программирование
tags: программирование, gitlab, git,
...
После помещения изменений (push) на сервер следует выполнять только задачи,
не требующие много ресурсов. Ресурсоёмкие задачи можно отложить на время
минимальной нагрузки сервера. Для этого нужно:
* в секциях файла `.gitlab-ci.yml`, запускающих задачи с высокой нагрузкой,
добавить
```yaml
only:
- schedules
```
подробнее это описано [здесь](https://docs.gitlab.com/ee/ci/yaml/#only-and-except-simplified)
* в веб-интерфейсе в меню **CI/CD** / **Расписания** добавить **Новое расписание**
и назначить исполнение задачи на время, когда нагрузка на сервер минимальна.
Для пропуска запланированной задачи в исполняемый скрипт нужно добавить
проверку условия запуска. Например, чтобы отменить запуск компиляции,
если за последний день (86400 секунд) не было изменений, можно оформить
`.gitlab-ci.yml` примерно так:
```yaml
nightly-job:
only:
- schedules
script:
- "[ $(($(date +%s)-$(git log -1 --date=format:%s --format=%cd))) -gt 86400 ] && exit 0"
- make
```

View File

@ -1,33 +1,31 @@
---
title: "Установка и настройка GitLab в LXC"
category: Программирование
tags: программирование, gitlab, git, lxc, контейнеры, ubuntu,
summary:
toc: yes
...
= Установка и настройка GitLab в LXC
:category: Программирование
:tags: программирование, gitlab, git, lxc, контейнеры, ubuntu,
[TOC]
:toc:
Установка выполняется в операционной системе Ubuntu Bionic.
### LXC
== LXC
Создание базового контейнера:
```sh
[source,sh]
----
lxc-create -t download -n bionic-base -- --dist ubuntu --release bionic --arch amd64
```
----
Создание контейнеров для GitLab и GitLab Runner:
```sh
[source,sh]
----
lxc-copy -n bionic-base -N gitlab-bionic -s
lxc-copy -n bionic-base -N gitlab-runner-bionic -s
```
----
Файл `/var/lib/lxc/gitlab-bionic/config`:
```
....
# Distribution configuration
lxc.include = /usr/share/lxc/config/common.conf
@ -50,11 +48,11 @@ lxc.autodev = 1
lxc.pty.max = 16384
lxc.cgroup.devices.allow = c 10:200 rwm
lxc.mount.entry = /dev/net dev/net none bind,create=dir
```
....
Файл `/var/lib/lxc/gitlab-runner-bionic/config`:
```
....
# Distribution configuration
lxc.include = /usr/share/lxc/config/common.conf
@ -82,65 +80,67 @@ lxc.autodev = 1
lxc.pty.max = 16384
lxc.cgroup.devices.allow = c 10:200 rwm
lxc.mount.entry = /dev/net dev/net none bind,create=dir
```
....
### GitLab
== GitLab
Установить GitLab:
```sh
[source,sh]
----
sudo lxc-start -n gitlab-bionic
sudo lxc-attach -n gitlab-bionic
sudo apt install curl
curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash
sudo apt install gitlab-ce
```
----
Отредактировать файл `/etc/locale.gen` и сгенерировать локали для системы:
Отредактировать файл `/etc/locale.gen` и сгенерировать локали для
системы:
```sh
[source,sh]
----
sudo locale-gen
```
----
Отредактировать файл `/etc/gitlab/gitlab.rb` и выполнить:
```sh
[source,sh]
----
sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart
```
----
### GitLab Runner и Docker
== GitLab Runner и Docker
Установить GitLab Runner:
```sh
[source,sh]
----
sudo lxc-start -n runner-bionic
sudo lxc-attach -n runner-bionic
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
sudo apt install gitlab-runner docker.io
sudo gitlab-runner register
```
----
Во время установки ввести токен приведённый на странице `admin/runners`,
а в качестве исполнителя задач `docker`.
Для работы Docker внутри контейнера нужно удалить AppArmor:
```sh
[source,sh]
----
sudo apt purge apparmor
```
----
Внутри контейнера для Docker желательно использовать драйвер `btrfs`
cat /etc/docker/daemon.json
Внутри контейнера для Docker желательно использовать драйвер `btrfs` cat
/etc/docker/daemon.json
{
"storage-driver": "btrfs"
}
\{ ``storage-driver'': ``btrfs'' }
== Ссылки
### Ссылки
* [GitLab Runner](https://docs.gitlab.com/runner/register/index.html)
* [Runners](https://docs.gitlab.com/ee/ci/runners/)
* [Gitlab-CI](https://habr.com/ru/company/southbridge/blog/306596/)
* https://docs.gitlab.com/runner/register/index.html[GitLab Runner]
* https://docs.gitlab.com/ee/ci/runners/[Runners]
* https://habr.com/ru/company/southbridge/blog/306596/[Gitlab-CI]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
= Библиотеки для C, C++
:category: Программирование
:tags: программирование, C, C++, Qt,
:toc:
== C
* http://nanomsg.org[nanomsg]: сетевое взаимодействие
* https://noping.cc[oping]: работа с ICMP-пакетами
* https://github.com/xianyi/OpenBLAS[openblas]: оптимизированная версия
https://ru.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms[BLAS]
== C++
* https://github.com/nlohmann/json[JSON]
* https://github.com/fmtlib/fmt[fmtlib]: форматирование строк
* https://github.com/gabime/spdlog[spdlog]: журналирование
* https://github.com/skystrife/cpptoml[cpptoml]: чтение
https://github.com/toml-lang/toml[TOML]
* https://github.com/martinmoene/gsl-lite/[gsl-lite]: реализация
рекомендаций https://github.com/isocpp/CppCoreGuidelines[C++ Core
Guidelines]
* http://www.holoborodko.com/pavel/mpfr[mpfrc++]: C++ интерфейс для
https://www.mpfr.org/[MPFR]
== Qt
* https://github.com/sjinks/qt_signalwatcher[Обработка сигналов UNIX]

View File

@ -1,30 +0,0 @@
---
title: "Библиотеки для C, C++"
category: Программирование
tags: программирование, C, C++, Qt,
summary:
toc: yes
...
[TOC]
### C
* [nanomsg](http://nanomsg.org): сетевое взаимодействие
* [oping](https://noping.cc): работа с ICMP-пакетами
* [openblas](https://github.com/xianyi/OpenBLAS): оптимизированная версия
[BLAS](https://ru.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms)
### C++
* [JSON](https://github.com/nlohmann/json)
* [fmtlib](https://github.com/fmtlib/fmt): форматирование строк
* [spdlog](https://github.com/gabime/spdlog): журналирование
* [cpptoml](https://github.com/skystrife/cpptoml): чтение [TOML](https://github.com/toml-lang/toml)
* [gsl-lite](https://github.com/martinmoene/gsl-lite/): реализация рекомедаций [C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines)
* [mpfrc++](http://www.holoborodko.com/pavel/mpfr): C++ интерфейс для [MPFR](https://www.mpfr.org/)
### Qt
* [Обработка сигналов UNIX](https://github.com/sjinks/qt_signalwatcher)

View File

@ -0,0 +1,151 @@
= Работа с датами и временем
:category: Программирование
:tags: программирование, время, часы, дата
:toc: auto
== Временные шкалы
В идеале системы учёта времени должны обладать тремя характеристиками:
. _точность_ (время базируется на атомном стандарте, каждая секунда
отсчитывается как секунда в системе СИ, нет високосных секунд, переводов
на зимнее или летнее время и т.п.);
. _простота_ (каждый '`день`' состоит из 86400 "`секунд`");
. _календарные дни_ (дни календаря точно соответствуют вращению Земли).
На практике есть возможность выбрать шкалу только с двумя
характеристиками из трёх.
. точность и календарные дни. Примером такой шкалы является UTC, в
которой отсчёт дней и секунд ведётся разными методами (секунды
исчисляются по атомному стандарту, а дни по суточному вращению Земли), а
соответствие достигается вводом _секунды координации_;
. календарные дни и простота. Примером такой шкалы является POSIX (IEEE
Std 1003.1-1988), в которой день всегда равен 86400 секундам;
. точность и простота. Этими характеристиками обладают технические шкалы
(атомные часы, GPS), в которых не важен учёт дней.
== Классы времени
Время можно условно поделить на два класса: физическое и гражданское.
. _Физическое_ время представляет собой точки на непрерывной шкале,
такую концепцию достаточно точно отражает UTC, если можно пренебречь
_секундой координации_ (дополнительная секунда, добавляемая к UTC 30
июня или 31 декабря для согласования со средним солнечным временем UT1.
В этот момент время условно обозначается как 23:59:60, а на шкале UTC
две секунды отображаются как одна).
. _Гражданское_ время представляется полями (год, месяц, число, час,
минута, секунда, доли секунды, а также временная зона и календарь,
который по умолчанию считается Григорианским).
Почти всегда существует возможность однозначно перевести физическое
время в гражданское и наоборот, но при этом следует различать их
свойства и применение (ближайшая аналогия — массивы байтов и символьные
строки).
Основная проблема состоит в том, что в обычном употреблении не всегда
можно сделать вывод о том, какой класс времени подразумевается, и
гражданское время меняется на основании юридических актов (указов,
постановлений и т.п.), что приводит к неоднозначности при планировании
событий.
== Обработка на компьютере
=== Хранение и отображение
Для ссылки на момент во времени необходимо использовать единую шкалу, на
которой нет разрывов, связанных с летним временем. Примером стандарта
времени с такой шкалой является UTC. Локальное или местное время для
таких целей не подходит, так как на его шкале имеются разрывы и
неоднозначности, связанные с переходами на летнее время и обратно.
Если нужно сохранить значение локального времени, то необходимо
сохранить также смещение относительно UTC, чтобы временную отметку можно
было интерпретировать однозначно. Необходимо помнить, что местное время
может отличаться от UTC на интервал не кратный часу (например, в
Нидерландах с 1909-05-01 по 1937-06-30 смещение времени от UTC
составляло 19 минут и 32.13 секунд).
Правила хранения и отображения времени:
. Время всегда хранится в UTC. При необходимости дополнительно
сохраняется информация о временной зоне (смещение и/или название).
. Для вывода на экран время переводится в местное.
. При выводе на экран отличного от местного времени необходимо указывать
название часового пояса или типа исчисления (например, Юлианский
календарь).
=== Системное время для администратора
Системный администратор должен следить за тем, чтобы файлы базы данных
описания временных зон *tzdata* имели одну версию в рамках комплекса и
обновлялись регулярно, чтобы минимизировать расхождения с внешними
системами. Особенно это важно делать при издании новых правил учёта
зимнего или летнего времени.
На серверах аппаратные часы всегда должны использовать UTC. Операционные
системы тоже должны использовать UTC, чтобы при возникновении проблем в
файлах журналов было указано время в едином формате.
В рамках комплекса следует использовать синхронизацию времени, даже если
нет доверенного источника более высокого уровня.
=== Клиентские приложения
В общем случае нельзя доверять временным отметкам внешних клиентов, так
как невозможно гарантировать их корректность. Программа должна
самостоятельно ставить временные отметки для происходящих событий.
Исключением являются программные комплексы, в которых предусмотрено
наличие доверенных приложений, ответственных за установку временных
отметок.
=== Postgresql
Сервер базы данных должен использовать только временную зону UTC. Для
этого в файле настройки сервера `postgresql.conf` должна быть строка
....
timezone = 'UTC'
....
При создании таблиц необходимо использовать типы данных
`timestamp without time zone` и `time without time zone`. Если данные о
времени должны содержать информацию о временной зоне или смещении
относительно UTC, то нужно создать дополнительные столбцы, информацию из
которых должно обрабатывать клиентское приложение. Например, временные
отметки можно хранить в таком виде
[source,sql]
----
CREATE TABLE time_stamps (
time_stamp time without time zone, -- временная отметка
time_zone character(12), -- текстовое название временной зоны
shift integer -- смещение локального времени относительно UTC в секундах
);
----
Смещение следует записывать в четырёхбайтное знаковое целое, так как оно
может быть как положительным, так и отрицательным, а его максимальное
значение может составлять 14 * 60 * 60 = 50400 секунд. Несмотря на
приведённый выше пример с временной зоной Нидерландов, микросекундами
можно пренебречь, так как современные временные зоны имеют смещения
кратные минутам, а точность до микросекунд в далёком прошлом обычно не
требуется.
Чтобы клиентская программа могла получить выборку, привязанную к
некоторой временной зоне можно использовать оператор `AT TIME ZONE`,
например
[source,sql]
----
SELECT TIMESTAMP '2001-02-16 20:38:40Z' AT TIME ZONE 'MSK';
----
В результате время будет преобразовано из временной зоны UTC в MSK.
Модификатор `Z` в записи времени указывает на принадлежность зоне UTC.
=== Qt
Класс `QTimeZone` предназначен для получения информации о временной зоне
и перевода времени из одной временной зоны в другую.

View File

@ -1,159 +0,0 @@
---
title: "Работа с датами и временем"
category: Программирование
tags: программирование, время, часы, дата,
summary:
toc: yes
toc-depth: 4
...
[TOC]
### Временные шкалы
В идеале системы учёта времени должны обладать тремя характеристиками:
1. очность_ (время базируется на атомном стандарте, каждая секунда
отсчитывается как секунда в системе СИ, нет високосных секунд, переводов
на зимнее или летнее время и т.п.);
2. _простота_ (каждый "день" состоит из 86400 "секунд");
3. алендарные дни_ (дни календаря точно соответствуют вращению Земли).
На практике есть возможность выбрать шкалу только с двумя характеристиками
из трёх.
1. точность и календарные дни. Примером такой шкалы является UTC,
в которой отсчёт дней и секунд ведётся разными методами (секунды
исчисляются по атомному стандарту, а дни по суточному вращению Земли),
а соответствие достигается вводом _секунды координации_;
2. календарные дни и простота. Примером такой шкалы является POSIX
(IEEE Std 1003.1-1988), в которой день всегда равен 86400 секундам;
3. точность и простота. Этими характеристиками обладают технические
шкалы (атомные часы, GPS), в которых не важен учёт дней.
### Классы времени
Время можно условно поделить на два класса: физическое и гражданское.
1. _Физическое_ время представляет собой точки на непрерывной шкале, такую
концепцию достаточно точно отражает UTC, если можно пренебречь _секундой
координации_ (дополнительная секунда, добавляемая к UTC 30 июня или 31 декабря
для согласования со средним солнечным временем UT1. В этот момент время
условно обозначается как 23:59:60, а на шкале UTC две секунды отображаются
как одна).
2. ражданское_ время представляется полями (год, месяц, число, час, минута,
секунда, доли секунды, а также временная зона и календарь, который по умолчанию
считается Григорианским).
Почти всегда существует возможность однозначно перевести физическое время
в гражданское и наоборот, но при этом следует различать их свойства и
применение (ближайшая аналогия — массивы байтов и символьные строки).
Основная проблема состоит в том, что в обычном употреблении не всегда можно
сделать вывод о том, какой класс времени подразумевается, и гражданское
время меняется на основании юридических актов (указов, постановлений и т.п.),
что приводит к неоднозначности при планировании событий.
### Обработка на компьютере
#### Хранение и отображение
Для ссылки на момент во времени необходимо использовать единую шкалу,
на которой нет разрывов, связанных с летним временем. Примером стандарта
времени с такой шкалой является UTC. Локальное или местное время для таких
целей не подходит, так как на его шкале имеются разрывы и неоднозначности,
связанные с переходами на летнее время и обратно.
Если нужно сохранить значение локального времени, то необходимо сохранить
также смещение относительно UTC, чтобы временную отметку можно было
интерпретировать однозначно. Необходимо помнить, что местное время может
отличаться от UTC на интервал не кратный часу (например, в Нидерландах
с 1909-05-01 по 1937-06-30 смещение времени от UTC составляло
19 минут и 32.13 секунд).
Правила хранения и отображения времени:
1. Время всегда хранится в UTC. При необходимости дополнительно сохраняется
информация о временной зоне (смещение и/или название).
2. Для вывода на экран время переводится в местное.
3. При выводе на экран отличного от местного времени необходимо указывать
название часового пояса или типа исчисления (например, Юлианский календарь).
#### Системное время для администратора
Системный администратор должен следить за тем, чтобы файлы базы данных
описания временных зон **tzdata** имели одну версию в рамках комплекса
и обновлялись регулярно, чтобы минимизировать расхождения с внешними
системами. Особенно это важно делать при издании новых правил учёта
зимнего или летнего времени.
На серверах аппаратные часы всегда должны использовать UTC. Операционные
системы тоже должны использовать UTC, чтобы при возникновении проблем
в файлах журналов было указано время в едином формате.
В рамках комплекса следует использовать синхронизацию времени, даже
если нет доверенного источника более высокого уровня.
#### Клиентские приложения
В общем случае нельзя доверять временным отметкам внешних клиентов,
так как невозможно гарантировать их корректность. Программа должна
самостоятельно ставить временные отметки для происходящих событий.
Исключением являются программные комплексы, в которых предусмотрено
наличие доверенных приложений, ответственных за установку временных отметок.
#### Postgresql
Сервер базы данных должен использовать только временную зону UTC. Для этого
в файле настройки сервера `postgresql.conf` должна быть строка
```
timezone = 'UTC'
```
При создании таблиц необходимо использовать типы данных `timestamp without time zone`
и `time without time zone`. Если данные о времени должны содержать информацию
о временной зоне или смещении относительно UTC, то нужно создать дополнительные
столбцы, информацию из которых должно обрабатывать клиентское приложение.
Например, временные отметки можно хранить в таком виде
```sql
CREATE TABLE time_stamps (
time_stamp time without time zone, -- временная отметка
time_zone character(12), -- текстовое название временной зоны
shift integer -- смещение локального времени относительно UTC в секундах
);
```
Смещение следует записывать в четырёхбайтное знаковое целое, так как оно
может быть как положительным, так и отрицательным, а его максимальное
значение может составлять 14 * 60 * 60 = 50400 секунд. Несмотря на приведённый
выше пример с временной зоной Нидерландов, микросекундами можно пренебречь,
так как современные временные зоны имеют смещения кратные минутам, а точность
до микросекунд в далёком прошлом обычно не требуется.
Чтобы клиентская программа могла получить выборку, привязанную к некоторой
временной зоне можно использовать оператор `AT TIME ZONE`, например
```sql
SELECT TIMESTAMP '2001-02-16 20:38:40Z' AT TIME ZONE 'MSK';
```
В результате время будет преобразовано из временной зоны UTC в MSK.
Модификатор `Z` в записи времени указывает на принадлежность зоне UTC.
#### Qt
Класс `QTimeZone` предназначен для получения информации о временной зоне
и перевода времени из одной временной зоны в другую.

19
wiki/Vim/Vimdiff.adoc Normal file
View File

@ -0,0 +1,19 @@
= Vim: сравнение файлов
:title-separator: {sp}|
:category: Vim
:tags: Vim, команды Vim,
Команды режима `diff` для сравнения и слияния файлов:
[cols="1,2",options="header",]
|===
|Команда |Назначение
|`do` |Получить изменения из второго окна в текущее окно
|`dp` |Вставить изменения из текущего окна во второе окно
|`]c` |Перейти к следующему отличию
|`[c` |Перейти к предыдущему отличию
|`C-W` `C-W` |Переход между окнами
|===
http://vimcasts.org/episodes/fugitive-vim-resolving-merge-conflicts-with-vimdiff/[Видеоурок]
по трехпутевому слиянию.

View File

@ -1,19 +0,0 @@
---
title: "Vim: сравнение файлов"
category: Vim
tags: Vim, команды Vim,
summary:
...
Команды режима `diff` для сравнения и слияния файлов:
Команда | Назначение
-------------|------------
`do` | Получить изменения из второго окна в текущее окно
`dp` | Вставить изменения из текущего окна во второе окно
`]c` | Перейти к следующему отличию
`[c` | Перейти к предыдущему отличию
`C-W` `C-W` | Переход между окнами
[Видеоурок](http://vimcasts.org/episodes/fugitive-vim-resolving-merge-conflicts-with-vimdiff/)
по трехпутевому слиянию.

View File

@ -0,0 +1,22 @@
= Vim: замена выделенного блока
:title-separator: {sp}|
:category: Vim
:tags: Vim, команды Vim,
Замену блока, выделенного в режиме VISUAL, можно выполнить
последовательностью команд `y:%s/<ctrl-r>"/заменитель/g`.
[cols="1,3",options="header",]
|===
|Команда |Назначение
|`y` |Копирование в регистр "
|`&#58;` |Перейти в командный режим
|`%` |Применить ко всему буферу
|`s` |Замена
|`Сtrl-r` |Вставка из регистра
|`&quot;` |Имя регистра (будет предложено по умолчанию)
|`/` |Разделитель
|`заменитель` |Новый текст
|`/` |Разделитель
|`g` |Для всех вхождений в строке
|===

View File

@ -1,23 +0,0 @@
---
title: "Vim: замена выделенного блока"
category: Vim
tags: Vim, команды Vim,
summary:
...
Замену блока, выделенного в режиме VISUAL, можно выполнить
последовательностью команд `y:%s/<ctrl-r>"/заменитель/g`.
Команда | Назначение
---------------|-------------
`y` | Копирование в регистр &quot;
`&#58;` | Перейти в командный режим
`%` | Применить ко всему буферу
`s` | Замена
`Сtrl-r` | Вставка из регистра
`&quot;` | Имя регистра (будет предложено по умолчанию)
`/` | Разделитель
`заменитель` | Новый текст
`/` | Разделитель
`g` | Для всех вхождений в строке

View File

@ -1,39 +1,40 @@
---
title: "Vim: клавиши Leader и LocalLeader"
category: Vim
tags: Vim, команды Vim,
summary:
...
= Vim: клавиши Leader и LocalLeader
:title-separator: {sp}|
:category: Vim
:tags: Vim, команды Vim,
Клавиши `Leader` и `LocalLeader` представляют собой префиксы для команд.
Их текущие значения можно посмотреть командами
```vim
[source,vim]
----
:echo mapleader
:echo maplocalleader
```
----
Часто их значения переназначают в файле `$HOME/.vimrc`, например так
Часто их значения переназначают в файле `$HOME/.vim/vimrc`, например так
```vim
[source,vim]
----
let mapleader = "\<Space>"
let maplocalleader = ","
```
----
Новое значение команды генерируется с помощью текущих значений этих
переменных, таким образом последовательность команд
```vim
[source,vim]
----
let mapleader = ","
nnoremap <Leader>a :echo "Hey there ,"<CR>
let mapleader = "\<Space>"
nnoremap <Leader>a :echo "Hey there space"<CR>
```
----
приведёт к тому, что будут созданы две команды `,a` и `<Space>a`,
следовательно для получения единообразных команд следует помещать
переназначения в начало файла `$HOME/.vimrc`.
переназначения в начало файла `$HOME/.vim/vimrc`.
`LocalLeader` отличается от `Leader` тем, что действует только для
текущего буфера, поэтому обычно используется в плагинах, загружаемых
@ -42,7 +43,7 @@ nnoremap <Leader>a :echo "Hey there space"<CR>
Таймауты для ввода команд, использующих клавиши `Leader` и
`LocalLeader`, настраиваются командой
```vim
[source,vim]
----
set timeout timeoutlen=5000 ttimeoutlen=100
```
----

View File

@ -1,14 +1,13 @@
---
title: "Vim: клавиши PageUp и PageDown"
category: Vim
tags: Vim, команды Vim,
summary:
...
= Vim: клавиши PageUp и PageDown
:title-separator: {sp}|
:category: Vim
:tags: Vim, команды Vim,
Чтобы поведение клавиш `PageUp` и `PageDown` совпадало с более
привычным, можно добавить в `$HOME/.vimrc` следующий код:
привычным, можно добавить в `$HOME/.vim/vimrc` следующий код:
```vim
[source,vim]
----
" Более привычные PgUp / PgDown, когда курсор остаётся в той же строке, "
" а не переносится вверх / вниз экрана, как при стандартном PgUp / PgDown. "
" Поскольку по умолчанию прокрутка по C-U / C-D, при которой курсор остаётся
@ -18,5 +17,4 @@ nmap <PageUp> <C-U><C-U>
nmap <PageDown> <C-D><C-D>
imap <PageUp> <C-O><C-U><C-O><C-U>
imap <PageDown> <C-O><C-D><C-O><C-D>
```
----

View File

@ -1,15 +1,14 @@
---
title: "Vim: кодировка файла"
category: Vim
tags: Vim,
summary:
...
= Vim: кодировка файла
:title-separator: {sp}|
:category: Vim
:tags: Vim,
Для управления кодировкой файлов можно создать дополнительное меню,
позволяющее открыть файл в выбранной кодировке, проверить её
корректность и сохранить в нужном виде. Пример кода:
```vim
[source,vim]
----
" кодировка для чтения файла
set encoding=utf-8
" кодировка терминала
@ -29,5 +28,4 @@ menu Encoding.Open\ as\ UCS-2LE :e ++enc=ucs-2le<CR>
menu Encoding.Open\ as\ UTF-8 :e ++enc=utf-8<CR>
menu Encoding.Convert\ to\ UTF-8 :set fenc=utf-8<CR>
map <F12> :emenu Encoding.<Tab>
```
----

View File

@ -0,0 +1,26 @@
= Vim: комментирование кода
:title-separator: {sp}|
:category: Vim
:tags: Vim, команды Vim,
Отмена автоматического комментирования кода при вставке из буфера:
[source,vim]
----
autocmd FileType * setlocal formatoptions-=cro
----
Для управления комментированием можно использовать плагин
https://github.com/scrooloose/nerdcommenter[NerdCommenter]. Основные
команды:
[cols="1,2",options="header",]
|===
|Команда |Назначение
|`[n]<leader>cc` |комментировать блок
|`[n]<leader>cn` |комментировать с учётом вложенности
|`[n]<leader>cl` |символ комментария помещать в начало строки
|`[n]<leader>ci` |инвертирование комментариев
|`<leader>cA` |добавить комментарий в конец строки
|`[n]<leader>cu` |раскомментировать блок
|===

View File

@ -1,26 +0,0 @@
---
title: "Vim: комментирование кода"
category: Vim
tags: Vim, команды Vim,
summary:
...
Отмена автоматического комментирования кода при вставке из буфера:
```Vim
autocmd FileType * setlocal formatoptions-=cro
```
Для управления комментированием можно использовать плагин
[NerdCommenter](https://github.com/scrooloose/nerdcommenter).
Основные команды:
Команда | Назначение
----------------------|----------------------------
`[n]<leader\>cc` | комментировать блок
`[n]<leader\>cn` | комментировать с учётом вложенности
`[n]<leader\>cl` | символ комментария помещать в начало строки
`[n]<leader\>ci` | инвертирование комментариев
`<leader\>cA` | добавить комментарий в конец строки
`[n]<leader\>cu` | раскомментировать блок

View File

@ -1,28 +1,28 @@
---
title: "Vim: менеджер плагинов Plug"
category: Vim
tags: Vim, плагины Vim,
summary:
...
= Vim: менеджер плагинов Plug
:title-separator: {sp}|
:category: Vim
:tags: Vim, плагины Vim,
Автоматическое управление плагинами в Vim можно организовать
с помощью менеджера [Plug](https://github.com/junegunn/vim-plug),
установить который можно командой
Автоматическое управление плагинами в Vim можно организовать с помощью
менеджера https://github.com/junegunn/vim-plug[Plug], установить который
можно командой
```sh
[source,sh]
----
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
```
----
Чтобы использовать Plug, нужно добавить в `$HOME/.vimrc`:
Чтобы использовать Plug, нужно добавить в `$HOME/.vim/vimrc`:
1. Строку `call plug#begin('~/.vim/plugged')`
2. Список строк, начинающихся с команды `Plug`, для загрузки плагинов
3. Закончить список командой `call plug#end()`
* Строку `call plug#begin('~/.vim/plugged')`
* Список строк, начинающихся с команды `Plug`, для загрузки плагинов
* Закончить список командой `call plug#end()`
Пример:
```vim
[source,vim]
----
" Обязательно использовать одиночные кавычки
call plug#begin('~/.vim/plugged')
@ -40,5 +40,4 @@ Plug 'tpope/vim-fireplace', { 'for': 'clojure' }
" Окончание списка плагинов
call plug#end()
```
----

View File

@ -1,15 +1,14 @@
---
title: "Vim: навигация по тексту с помощью easymotion"
category: Vim
tags: Vim, команды Vim,
summary:
...
= Vim: навигация по тексту с помощью easymotion
:title-separator: {sp}|
:category: Vim
:tags: Vim, команды Vim,
Плагин [easymotion](https://github.com/easymotion/vim-easymotion)
предоставляет функции для удобного перемещения по тексту.
Пример настройки:
Плагин https://github.com/easymotion/vim-easymotion[easymotion]
предоставляет функции для удобного перемещения по тексту. Пример
настройки:
```vim
[source,vim]
----
" Не включать команды по умолчанию
let g:EasyMotion_do_mapping = 0
@ -49,5 +48,4 @@ omap / <Plug>(easymotion-tn)
" different highlight method and have some other features )
map n <Plug>(easymotion-next)
map N <Plug>(easymotion-prev)
```
----

View File

@ -0,0 +1,15 @@
= Vim: навигация по буферам
:title-separator: {sp}|
:category: Vim
:tags: Vim, команды Vim,
[cols="1,2",options="header",]
|===
|Команда |Назначение
|`:bn` |следующий буфер
|`:bp` |предыдущий буфер
|`:ls` |список открытых буферов
|`:bd` |закрыть текущий буфер
|`:b имя_буфера` |переключиться на буфер
|`:bdа имя_буфера` |удалить буфер по имени
|===

View File

@ -1,16 +0,0 @@
---
title: "Vim: навигация по буферам"
category: Vim
tags: Vim, команды Vim,
summary:
...
Команда | Назначение
------------------|-----------------
`:bn` | следующий буфер
`:bp` | предыдущий буфер
`:ls` | список открытых буферов
`:bd` | закрыть текущий буфер
`:b имя_буфера` | переключиться на буфер
`:bdа имя_буфера` | удалить буфер по имени

View File

@ -1,14 +1,13 @@
---
title: "Vim: нумерация строк"
category: Vim
tags: Vim, команды Vim,
summary:
...
= Vim: нумерация строк
:title-separator: {sp}|
:category: Vim
:tags: Vim, команды Vim,
Для переключения режимов отображения слева столбца нумерации
строк можно добавить в `$HOME/.vimrc` следующий код:
Для переключения режимов отображения слева столбца нумерации строк можно
добавить в `$HOME/.vimrc` следующий код:
```vim
[source,vim]
----
" Нумерация строк включена
set number
" Нумерация строк абсолютная
@ -28,7 +27,7 @@ function! ChangeNumbering()
endfunc
map <LocalLeader># <Esc>:call ChangeNumbering()<CR>
```
----
В результате по команде `<LocalLeader>#` будет осуществляться
циклическое переключение между абсолютной, относительной нумерацией

View File

@ -1,14 +1,13 @@
---
title: "Vim: проверка орфографии"
category: Vim
tags: Vim, команды Vim, словарь, орфография,
summary:
...
= Vim: проверка орфографии
:title-separator: {sp}|
:category: Vim
:tags: Vim, команды Vim, словарь, орфография,
Код в `$HOME/.vimrc` для циклического переключения режимов проверки
Код в `$HOME/.vim/vimrc` для циклического переключения режимов проверки
орфографии: два языка, английский, русский и без проверки:
```Vim
[source,vim]
----
" По умолчанию проверка орфографии для русского и английского.
setlocal spell spelllang=ru,en
set spellsuggest=9
@ -35,5 +34,4 @@ map <C-F7> <Esc>:call ChangeSpellLang()<CR>
" выбор альтернатив
imap <F7> <Esc> z=<CR>i
map <F7> z=<CR>
```
----

View File

@ -0,0 +1,11 @@
= Vim: полезные ссылки
:title-separator: {sp}|
:category: Vim
:tags: Vim,
* http://vim.org[Vim]
* http://usevim.com/[Usevim]
* http://nvie.com/posts/how-i-boosted-my-vim/[How I boosted my Vim]
* https://sheerun.net/2014/03/21/how-to-boost-your-vim-productivity/[How
to boost your Vim productivity]
* https://vimawesome.com/[Vim Awesome]

View File

@ -1,12 +0,0 @@
---
title: "Vim: полезные ссылки"
category: Vim
tags: Vim,
summary:
...
* [Vim](http://vim.org)
* [Usevim](http://usevim.com/)
* [How I boosted my Vim](http://nvie.com/posts/how-i-boosted-my-vim/)
* [How to boost your Vim productivity](https://sheerun.net/2014/03/21/how-to-boost-your-vim-productivity/)
* [Vim Awesome](https://vimawesome.com/)

View File

@ -0,0 +1,20 @@
= Vim: управление окнами
:title-separator: {sp}|
:category: Vim
:tags: Vim, команды Vim,
[cols="1,2",options="header",]
|===
|Команда |Назначение
|`:split filename` |открыть в новом окне (горизонтальное разделение)
|`:vsplit filename` |открыть в новом окне (вертикальное разделение)
|`<C-W>` `<C-W>` |перейти к следующему окну
|`<C-W>` `q` |закрыть текущее окно
|`<C-W>` `o` |развернуть окно полностью
|`<C-W>` `pass:c[_]` |развернуть окно по высоте
|`<C-W>` `\|` |развернуть окно по ширине
|`<C-W>` `=` |выровнять размер окон
|`<C-W>` `+` |увеличить окно на 1 строку
|`<C-W>` `-` |уменьшить окно на 1 строку
|`<C-W>` `стрелки` |перемещение между окнами
|===

View File

@ -1,21 +0,0 @@
---
title: "Vim: управление окнами"
category: Vim
tags: Vim, команды Vim,
summary:
...
Команда | Назначение
--------------------|-------------------------
`:split filename` | открыть в новом окне (горизонтальное разделение)
`:vsplit filename` | открыть в новом окне (вертикальное разделение)
`<C-W>` `<C-W>` | перейти к следующему окну
`<C-W>` `q` | закрыть текущее окно
`<C-W>` `o` | развернуть окно полностью
`<C-W>` `_` | развернуть окно по высоте
`<C-W>` `|` | развернуть окно по ширине
`<C-W>` `=` | выровнять размер окон
`<C-W>` `+` | увеличить окно на 1 строку
`<C-W>` `-` | уменьшить окно на 1 строку
`<C-W>` `стрелки` | перемещение между окнами

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB