Compare commits

...

216 Commits

Author SHA1 Message Date
9206a9ff3a Все подмодули на собственном сервере 2022-01-15 16:44:37 +03:00
25b194750e Обновление 2022-01-15 15:36:41 +03:00
25491b80c4 Обновление 2021-12-24 16:51:35 +03:00
8c3a99eff9 Обновление 2021-12-24 16:02:12 +03:00
a2cca2dd8c Обновление 2021-12-13 23:10:12 +03:00
8e3f80d82c Обновление 2021-10-20 10:11:49 +03:00
763ec72402 Обновление 2021-08-27 12:15:49 +03:00
7505316c2c Обновление 2021-06-08 11:22:28 +03:00
8639788c93 update 2020-11-02 09:43:29 +03:00
0e27e5e68d update 2020-11-02 08:14:58 +03:00
578274e444 Обновление подмодулей 2020-10-11 21:01:41 +03:00
2de1503574 Обновление 2020-10-11 20:49:26 +03:00
64e5aa161f Обновление 2020-10-11 20:48:22 +03:00
2b629c9dc9 Правка 2020-06-30 16:30:57 +03:00
6579472659 update 2020-05-01 17:17:34 +03:00
61fa5230ae update 2020-04-29 14:08:15 +03:00
dd840cdbc9 update 2020-04-24 22:25:49 +03:00
8fa46a57be update 2020-04-24 22:23:00 +03:00
e1bfd02131 update 2020-04-24 22:19:20 +03:00
0afb335879 update 2020-04-24 22:18:54 +03:00
daf7136008 update 2020-04-24 22:09:59 +03:00
d14d71910c update 2020-04-24 22:07:03 +03:00
1c6f6c4945 update 2020-04-24 21:56:56 +03:00
bf875c1842 update 2020-04-24 21:52:36 +03:00
373fe00cb3 update 2020-04-24 21:48:16 +03:00
b2cfbfafca update 2020-04-24 21:43:15 +03:00
c3930f59f9 update 2020-04-24 21:41:09 +03:00
1a7e8c5a56 update 2020-04-24 21:38:35 +03:00
2af87bc633 update 2020-04-24 21:35:56 +03:00
5b2ac484f8 update 2020-04-24 21:17:29 +03:00
cc81e6ac8c update 2020-04-24 21:14:17 +03:00
79193d4152 update 2020-04-22 23:07:53 +03:00
71cbd8a230 update 2020-04-22 14:14:07 +03:00
11d1c31ce7 update 2020-04-21 09:03:22 +03:00
6353b7839e update 2020-04-21 08:54:54 +03:00
4fdc1e4951 update 2020-04-21 06:43:14 +03:00
562d2ecddf update 2020-04-21 06:42:52 +03:00
101ea1880d update 2020-04-21 06:13:09 +03:00
72e6b66a52 qa 2020-04-21 06:02:52 +03:00
3617a09b2e update 2020-04-20 23:41:13 +03:00
3d3aac6206 update 2020-04-20 23:33:51 +03:00
12c6f6396f update 2020-04-20 23:27:44 +03:00
6897baf6c6 update 2020-04-20 23:27:17 +03:00
8b92ccf57a update 2020-04-20 23:26:37 +03:00
057a213a80 update 2020-04-20 23:17:35 +03:00
af643e1e35 update 2020-04-20 22:57:17 +03:00
363822b166 update 2020-04-20 22:48:38 +03:00
c723a9d7b5 update 2020-04-20 22:38:06 +03:00
33ead8f7e6 update 2020-04-20 22:32:29 +03:00
3cfc262a3d update 2020-04-20 22:19:11 +03:00
bc250dd0bf update 2020-04-20 22:12:56 +03:00
0d83b3637c update 2020-04-20 22:10:35 +03:00
6bd1d03d3b update 2020-04-20 22:04:39 +03:00
32853cc8f4 update 2020-04-20 22:00:59 +03:00
311c812181 update 2020-04-19 12:19:24 +03:00
d4bc574a94 update 2020-04-19 12:16:43 +03:00
876ff1ade5 update 2020-04-19 12:10:42 +03:00
afa58987da update 2020-04-19 12:05:06 +03:00
0643cb5f73 Обновление 2020-04-19 11:59:02 +03:00
4717bd0336 update 2020-04-19 11:36:02 +03:00
36d088e75c clazy 2020-04-19 11:31:30 +03:00
ac859dc4ec update 2020-04-16 15:50:41 +03:00
e0a18fc66d update 2020-04-16 12:47:23 +03:00
b0a8898f1f update 2020-04-16 10:12:02 +03:00
9857fa778d update 2020-04-16 10:01:56 +03:00
7da59f9b83 update 2020-04-16 09:50:22 +03:00
e208752f44 update 2020-04-16 09:40:45 +03:00
78ecf3b655 update 2020-04-16 09:30:46 +03:00
12dbf54505 update 2020-04-16 09:27:26 +03:00
3858c49164 Пример подключения переводов 2020-04-16 01:05:11 +03:00
dfd884e36b Правильная локализация 2020-04-16 01:03:34 +03:00
31c6c022bc Варианты сборки в одном файле настройки 2020-04-15 19:12:49 +03:00
e243b899b3 update 2020-04-15 18:56:04 +03:00
84990e2821 update 2020-04-15 10:32:44 +03:00
16e8ef3bdb update 2020-04-15 10:00:09 +03:00
9a9bea6b1b update 2020-04-14 23:10:26 +03:00
fc6b02c833 update 2020-04-14 22:59:24 +03:00
329145eb50 update 2020-04-14 21:52:10 +03:00
7cab7eab1b update 2020-04-14 19:43:31 +03:00
fa7da4ab1b update 2020-04-14 17:23:07 +03:00
303837da8e update 2020-04-14 17:04:45 +03:00
0f27298764 update 2020-04-14 16:57:28 +03:00
2a6147b3db update 2020-04-14 16:55:21 +03:00
de13ec6e73 update 2020-04-14 16:54:05 +03:00
dc59d8785d update 2020-04-14 16:37:35 +03:00
12b1019cab update 2020-04-14 16:27:02 +03:00
4b640a0a34 update 2020-04-14 14:20:29 +03:00
8750675e43 update 2020-04-14 13:45:26 +03:00
5761bcb0fc update 2020-04-14 13:35:51 +03:00
9530058f05 update 2020-04-14 13:25:21 +03:00
ee4f156901 update 2020-04-14 13:19:33 +03:00
019eea73cf update 2020-04-14 13:10:34 +03:00
16f6a40456 update 2020-04-14 12:37:56 +03:00
3a2222cde3 update 2020-04-14 12:31:39 +03:00
8a4866ce9f update 2020-04-14 12:17:22 +03:00
2d0baaf290 update 2020-04-14 11:56:35 +03:00
3ca7530a29 update 2020-04-14 10:01:33 +03:00
6d71ca630a update 2020-04-14 09:43:55 +03:00
cf7d33f8b2 update 2020-04-14 09:37:33 +03:00
5f85ae0f8f update 2020-04-14 01:26:01 +03:00
9b4fe8fdb1 update 2020-04-14 01:11:23 +03:00
c89fed2c07 update 2020-04-14 00:57:48 +03:00
c22fcdfdd8 update 2020-04-13 13:22:56 +03:00
65a80b8d80 update 2020-04-13 13:18:15 +03:00
634cce1c8d update 2020-04-13 12:45:11 +03:00
ec06dd2a01 update 2020-04-13 12:31:59 +03:00
6d0d152039 update 2020-04-13 12:23:07 +03:00
2d8a272d2d update 2020-04-13 12:17:34 +03:00
59492ba5c6 update 2020-04-13 12:09:20 +03:00
e9970d2b2b update 2020-04-13 12:06:11 +03:00
bdda710617 update 2020-04-13 11:52:00 +03:00
e4d5715a06 update 2020-04-13 11:47:19 +03:00
3fe8173a31 update 2020-04-13 11:35:56 +03:00
ed3f6faa1b update 2020-04-13 11:31:26 +03:00
65007b699d update 2020-04-13 11:25:28 +03:00
0160aab51f update 2020-04-13 11:19:37 +03:00
4bdb12c95e update 2020-04-13 11:06:07 +03:00
305da06de1 update 2020-04-13 11:05:48 +03:00
e1873d9579 update 2020-04-13 10:54:15 +03:00
5facc2edd6 update 2020-04-13 10:33:11 +03:00
37e74cdbaf update 2020-04-13 10:02:30 +03:00
8f38d1d96c update 2020-04-13 10:00:26 +03:00
964fb48b9a update 2020-04-13 09:11:58 +03:00
78505cfa75 update 2020-04-13 09:08:14 +03:00
5602fbc30e update 2020-04-12 20:04:35 +03:00
0f1804e3fb gitignore 2020-04-12 19:59:32 +03:00
c6648d7ae8 update 2020-04-12 19:46:33 +03:00
b9ef4fb756 update 2020-04-12 17:13:09 +03:00
002213aa87 Важное изменение в настройках для переводов 2020-04-12 17:08:45 +03:00
ac5e2dd88e update 2020-04-11 23:58:43 +03:00
b7d2c2e280 update 2020-04-11 23:09:16 +03:00
40fac363ce update 2020-04-11 22:54:03 +03:00
b8d878287c update 2020-04-11 22:43:14 +03:00
a6d0505adb update 2020-04-11 22:00:06 +03:00
c99b5f0559 update 2020-04-11 21:53:54 +03:00
5fa1f983b8 update 2020-04-11 21:48:55 +03:00
5eb808d587 update 2020-04-11 21:20:55 +03:00
ee24a0d933 update 2020-04-11 21:06:02 +03:00
7430389f3c update 2020-04-11 20:59:22 +03:00
d84e23e0ad update 2020-04-11 20:49:41 +03:00
221a63a827 update 2020-04-11 20:44:28 +03:00
07bafa380d update 2020-04-11 20:36:44 +03:00
83f97f482e images 2020-04-11 20:20:31 +03:00
321e48c500 update 2020-04-11 20:16:51 +03:00
22067a2a3d update 2020-04-11 20:09:43 +03:00
494c9f31d6 update 2020-04-11 19:44:15 +03:00
2bcf387ba4 update 2020-04-11 18:07:10 +03:00
5bf5a20624 update 2020-04-11 16:19:35 +03:00
fff4e996d2 update 2020-04-11 15:13:41 +03:00
218f22c8d2 Merge branch 'master' of git.246060.ru:/f1x1t/dsp-site 2020-04-11 15:10:08 +03:00
d931b5aaea update 2020-04-11 14:57:13 +03:00
ec16a3a380 update 2020-04-10 18:13:06 +03:00
c41683d9e2 update 2020-04-10 18:10:40 +03:00
2abd41f429 update 2020-04-10 10:59:43 +03:00
f0cba8e7f6 update 2020-04-09 20:59:56 +03:00
8e1b48e868 update 2020-04-09 20:43:02 +03:00
d3fe32a96b update 2020-04-09 20:41:13 +03:00
62ab8db450 update 2020-04-09 20:39:10 +03:00
2af67616c8 update 2020-04-09 20:35:09 +03:00
d07e6a66f8 update 2020-04-09 20:10:52 +03:00
51adf6eb5a update 2020-04-09 19:23:16 +03:00
007afda3d1 update 2020-04-08 20:09:58 +03:00
3355f9185e update 2020-04-06 08:49:00 +03:00
1e5b6aa485 update 2020-04-04 11:51:36 +03:00
679bf869e8 Merge branch 'adoc' 2019-08-30 09:31:00 +03:00
1aaacb1df7 cmake 2019-08-29 17:34:57 +03:00
c36bbc9678 local 2019-08-29 17:19:41 +03:00
1068f502bb update 2019-07-15 21:47:09 +03:00
5661034292 Qt: Обмен бинарными данными 2019-06-20 06:56:39 +03:00
322cd0643e next 2019-06-03 16:39:27 +03:00
bf0c4a6c26 next 2019-06-03 10:49:50 +03:00
3b34f960b5 Merge branch 'asciidoc' 2019-06-03 10:04:55 +03:00
02568f482b text 2019-06-03 10:03:24 +03:00
e312541ae7 orfo 2019-06-03 02:26:28 +03:00
f3206726a0 text 2019-06-02 19:31:29 +03:00
adb7098d1c next 2019-06-02 19:30:00 +03:00
f56fff2bd3 Тема 2019-06-02 13:26:42 +03:00
d02e8b7e76 next 2019-06-02 13:20:51 +03:00
82ae133e81 asciidoc вместо markdown 2019-06-02 00:08:41 +03:00
f8a740a624 text 2019-05-28 15:57:56 +03:00
0003a98c30 text 2019-05-28 14:15:34 +03:00
0bc4923a7b text 2019-05-28 13:33:01 +03:00
71dd5de667 text 2019-05-27 17:46:54 +03:00
25d7d9850c text 2019-05-27 12:00:49 +03:00
1554d6aca1 Настройки 2019-05-27 12:00:41 +03:00
ac17c51a6e next 2019-05-27 08:45:29 +03:00
b1f569977e Merge branch 'master' of git.246060.ru:/f1x1t/dsp-site 2019-05-25 21:45:05 +03:00
f48a608249 git: основные команды 2019-05-24 07:56:12 +03:00
02dddfeb08 Настройки 2019-05-24 07:55:47 +03:00
11e041c59a make clean 2019-05-21 16:40:39 +03:00
e250b413fc Merge branch 'master' of git.246060.ru:/f1x1t/dsp-site 2019-04-29 08:24:24 +03:00
53373f0be9 README 2019-04-26 16:24:15 +03:00
c25940b9ca Text 2019-04-26 16:22:16 +03:00
b0daad8429 Ignore upload.sh 2019-04-26 12:53:50 +03:00
0679f82298 replacer plugin 2019-04-26 12:53:19 +03:00
2d1ac5eaf9 Text 2019-04-26 11:23:35 +03:00
9644c34ed2 Text 2019-04-26 10:56:04 +03:00
4318bc1677 Text 2019-04-26 07:54:06 +03:00
c36634d58b Text 2019-04-25 16:20:30 +03:00
6c5c15bc3e Text 2019-04-25 08:38:31 +03:00
8425adae8e Tables 2019-04-24 18:36:43 +03:00
680be26063 Makefile 2019-04-24 17:17:25 +03:00
09fb3f3d13 Text 2019-04-24 17:17:12 +03:00
7c828b9ba2 Theme 2019-04-24 16:57:27 +03:00
0fb346107f Text 2019-04-24 16:57:04 +03:00
83024d70bc Text 2019-04-24 08:20:13 +03:00
27e60f978e Tags 2019-04-23 20:40:06 +03:00
e472ec35f1 Text 2019-04-23 19:40:55 +03:00
e1f52e7b0a Text 2019-04-23 16:08:36 +03:00
66832b7fbe Text 2019-04-23 15:54:33 +03:00
7c64668e7f Text 2019-04-23 14:53:16 +03:00
324f564aeb Text 2019-04-22 11:59:44 +03:00
43c149b481 Text 2019-04-22 08:13:35 +03:00
d8e0ffcd66 Text 2019-04-21 13:26:36 +03:00
8c9e7d3f4a Correct yui compressor options 2019-04-21 13:26:02 +03:00
fd8f3bbc38 Config to production generation 2019-04-21 13:25:31 +03:00
152 changed files with 7346 additions and 2999 deletions

12
.gitignore vendored
View File

@ -1,6 +1,18 @@
/.asciidoctor
cache/*
cache-ascii/*
cache-full/*
cache-html/*
output/*
__pycache__
wiki/trash
wiki/notes.sqlite
upload.sh
wiki/**/diag*.png
wiki/**/*.png.cache
*.pyc
*.txt
upload-*.sh

29
.gitmodules vendored
View File

@ -1,18 +1,27 @@
[submodule "plugins/thirdparty/md-metayaml"]
path = plugins/thirdparty/md-metayaml
url = git@git.246060.ru:/f1x1t/pelican-md-metayaml.git
[submodule "plugins/thirdparty/pelican-css"]
path = plugins/thirdparty/pelican-css
url = https://notabug.org/jorgesumle/pelican-css
[submodule "plugins/official"]
path = plugins/official
url = git@github.com:/getpelican/pelican-plugins.git
url = git@git.246060.ru:f1x1t/pelican-md-metayaml.git
[submodule "themes/bootstrap4"]
path = themes/bootstrap4
url = git@git.246060.ru:/f1x1t/pelican-theme-bootstrap4.git
url = git@git.246060.ru:f1x1t/pelican-theme-bootstrap4.git
[submodule "plugins/thirdparty/yuicompressor-opt"]
path = plugins/thirdparty/yuicompressor-opt
url = git@git.246060.ru:/f1x1t/pelican-yuicompressor-opt.git
url = git@git.246060.ru:f1x1t/pelican-yuicompressor-opt.git
[submodule "plugins/thirdparty/pelidoc"]
path = plugins/thirdparty/pelidoc
url = git@git.246060.ru:/f1x1t/pelican-pelidoc.git
url = git@git.246060.ru:f1x1t/pelican-pelidoc.git
[submodule "plugins/thirdparty/pandoc_reader"]
path = plugins/thirdparty/pandoc_reader
url = git@git.246060.ru:f1x1t/pelican-pandoc-reader
[submodule "plugins/thirdparty/asciidoctor"]
path = plugins/thirdparty/asciidoctor
url = git@git.246060.ru:f1x1t/pelican-asciidoctor
[submodule "plugins/thirdparty/replacer"]
path = plugins/thirdparty/replacer
url = git@git.246060.ru:f1x1t/pelican-replacer
[submodule "plugins/thirdparty/pelican-css"]
path = plugins/thirdparty/pelican-css
url = git@git.246060.ru:f1x1t/pelican-css
[submodule "plugins/official"]
path = plugins/official
url = git@git.246060.ru:f1x1t/pelican-plugins-official

9
Makefile Normal file
View File

@ -0,0 +1,9 @@
build:
pelican -s pelicanconf.py
web:
COMPRESS=1 pelican -s pelicanconf.py
clean:
rm -rf cache __pycache__

View File

@ -1,6 +1,11 @@
Сайт ДСП
========
```sh
sudo apt-get install pelican plantuml yui-compressor
sudo gem install asciidoctor asciidoctor-pdf asciidoctor-diagram
```
Установка:
```sh
@ -11,6 +16,9 @@ git submodule update --init plugins/official
git submodule update --init plugins/thirdparty/pelican-css
git submodule update --init plugins/thirdparty/pelidoc
git submodule update --init plugins/thirdparty/yuicompressor-opt
git submodule update --init plugins/thirdparty/pandoc_reader
git submodule update --init plugins/thirdparty/replacer
git submodule update --init plugins/thirdparty/asciidoctor
git submodule update --init themes/bootstrap4
```

View File

@ -1,33 +1,6 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# -*- coding: utf-8 -*- #
from __future__ import unicode_literals
class i18n(object):
# looks for translations in
# {LOCALE_DIR}/{LANGUAGE}/LC_MESSAGES/{DOMAIN}.mo
# if not present, falls back to default
DOMAIN = 'messages'
LOCALE_DIR = '{THEME}/translations'
LANGUAGES = ['ru']
NEWSTYLE = True
__name__ = 'i18n'
def register(self):
from pelican.signals import generator_init
generator_init.connect(self.install_translator)
def install_translator(self, generator):
import gettext
try:
translator = gettext.translation(
self.DOMAIN,
self.LOCALE_DIR.format(THEME=THEME),
self.LANGUAGES)
except (OSError, IOError):
translator = gettext.NullTranslations()
generator.env.install_gettext_translations(translator, self.NEWSTYLE)
import os
# ABOUT_ME = ' '
AUTHOR = 'Андрей Астафьев'
@ -35,6 +8,7 @@ SITENAME = 'ДСП'
SITEURL = 'https://dsp.246060.ru'
PATH = 'wiki'
CACHE_PATH = 'cache'
TIMEZONE = 'Europe/Moscow'
@ -52,18 +26,11 @@ AUTHOR_FEED_ATOM = None
AUTHOR_FEED_RSS = None
USE_FOLDER_AS_CATEGORY = True
DEFAULT_DATE = 'fs'
STATIC_PATHS = [ 'images', 'files' ]
STATIC_PATHS = [ 'images', 'files', 'extras' ]
DIRECT_TEMPLATES = ('index', 'categories', 'authors', 'archives', 'search')
MARKDOWN = {
'extension_configs': {
'markdown.extensions.codehilite': {'css_class': 'highlight'},
'markdown.extensions.extra': {},
'markdown.extensions.meta': {},
'markdown.extensions.toc': {
'title': 'Содержание'
},
} ,
'output_format': 'html5',
EXTRA_PATH_METADATA = {
'extras/favicon.ico': {'path': 'favicon.ico'},
}
DISPLAY_CATEGORIES_ON_MENU = False
@ -73,44 +40,45 @@ DISPLAY_TAGS_ON_SIDEBAR = True
THEME = 'themes/bootstrap4'
BOOTSTRAP_THEME = 'litera'
I18N_TEMPLATES_LANG = 'ru'
# I18N_GETTEXT_LOCALEDIR = 'translations'
# I18N_GETTEXT_DOMAIN = 'messages'
# Обязательно в виде массива
I18N_TEMPLATES_LANG = ['ru']
I18N_GETTEXT_NEWSTYLE = True
I18N_GETTEXT_LOCALEDIR = 'themes/bootstrap4/translations'
I18N_GETTEXT_DOMAIN = 'messages'
JINJA_ENVIRONMENT = {'extensions': ['jinja2.ext.i18n']}
PLUGIN_PATHS = ["plugins/official", "plugins/thirdparty"]
PLUGINS = [i18n(), "pelidoc", "md-metayaml", "render_math", "series", "subcategory", "tag_cloud", "tipue_search", "pelican-css"]
#PLUGINS = ["better_tables", "just_table"]
PLUGINS = ["i18n_subsites", "pelican-css", "series", "subcategory", "tag_cloud", "tipue_search", "replacer", "asciidoctor"]
#PDF_PROCESSOR = True
PANDOC_OUTPUTS = {
'pdf': 'pdf',
}
PANDOC_EXTRA_OPTIONS = [
"-V", "documentclass:extarticle",
"-V", "toc-title:Содержание",
"-F", "skip-toc-tag",
"--highlight-style=tango",
"--resource-path=wiki",
"--template=wiki",
"--pdf-engine=xelatex"
ASCIIDOCTOR_CMD = "asciidoctor"
ASCIIDOCTOR_EXTRA_OPTIONS = [
'--require', 'asciidoctor-diagram',
'--require', '{}/themes/pdf/qa.rb'.format(os.getcwd()),
'--attribute=imagesdir={}/wiki/images'.format(os.getcwd()),
'--attribute=source-highlighter=pygments',
'--attribute=pygments-style=manni',
'--attribute=pygments-css=class',
'--attribute=lang=ru',
'--attribute=l10ndir={}/themes/l10n'.format(os.getcwd()),
'--attribute=experimental',
'--attribute=pdf-themesdir={}/themes/pdf'.format(os.getcwd()),
'--attribute=pdf-theme=wiki',
]
PANDOC_MARKDOWN_EXTENSIONS = [
"+smart",
"+backtick_code_blocks",
"+fenced_code_blocks",
"+fenced_code_attributes"
]
REPLACES = (
('{}/wiki/'.format(os.getcwd()), u''),
)
#YUICOMPRESSOR_EXECUTABLE = "yui-compressor"
#YUICOMPRESSOR_EXTRA_OPTIONS = ["--disable-optimizations"]
#PLUGINS += ["yuicompressor-opt"]
YUICOMPRESSOR_EXECUTABLE = "yui-compressor"
YUICOMPRESSOR_EXTRA_OPTIONS = ["--nomunge"]
DIRECT_TEMPLATES = ('index', 'categories', 'authors', 'archives', 'search')
if 'COMPRESS' in os.environ:
PLUGINS += ["yuicompressor-opt"]
PDF_PROCESSOR = True
# Blogroll
LINKS = ()
@ -124,7 +92,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
plugins/thirdparty/replacer vendored Submodule

23
themes/l10n/ru.adoc Normal file
View File

@ -0,0 +1,23 @@
// Russian translation, courtesy of Alexander Zobkov <alexander.zobkov@gmail.com>
:appendix-caption: Приложение
:appendix-refsig: {appendix-caption}
:caution-caption: Внимание
:chapter-label: Глава
:chapter-refsig: {chapter-label}
:example-caption: Пример
:figure-caption: Рисунок
:important-caption: Важно
:last-update-label: Последнее обновление
ifdef::listing-caption[:listing-caption: Листинг]
ifdef::manname-title[:manname-title: Название]
:note-caption: Примечание
:part-label: Часть
:part-refsig: {part-label}
ifdef::preface-title[:preface-title: Предисловие]
:section-refsig: Раздел
:table-caption: Таблица
:tip-caption: Подсказка
:toc-title: Содержание
:untitled-label: Без названия
:version-label: Версия
:warning-caption: Предупреждение

60
themes/pdf/qa.rb Normal file
View File

@ -0,0 +1,60 @@
require 'asciidoctor/extensions'
class QuestionBlock < Asciidoctor::Extensions::BlockProcessor
use_dsl
named :QUESTION
on_context :example
def process parent, reader, attrs
attrs['name'] = 'question'
attrs['caption'] = 'Question'
admon = create_block parent, :admonition, nil, attrs, content_model: :compound
parse_content admon, reader
admon
end
end
class QuestionBlockCss < Asciidoctor::Extensions::DocinfoProcessor
use_dsl
def process doc
'<style>
.admonitionblock td.icon .icon-question:before{content:"\f128";color:#000}
</style>'
end
end
Asciidoctor::Extensions.register do
block QuestionBlock
docinfo_processor QuestionBlockCss
end
class AnswerBlock < Asciidoctor::Extensions::BlockProcessor
use_dsl
named :ANSWER
on_context :example
def process parent, reader, attrs
attrs['name'] = 'answer'
attrs['caption'] = 'Answer'
admon = create_block parent, :admonition, nil, attrs, content_model: :compound
parse_content admon, reader
admon
end
end
class AnswerBlockCss < Asciidoctor::Extensions::DocinfoProcessor
use_dsl
def process doc
'<style>
.admonitionblock td.icon .icon-answer:before{content:"\f0eb";color:#000}
</style>'
end
end
Asciidoctor::Extensions.register do
block AnswerBlock
docinfo_processor AnswerBlockCss
end

22
themes/pdf/wiki-theme.yml Normal file
View File

@ -0,0 +1,22 @@
extends: default
page:
size: A4
layout: portrait
# margin: [15mm, 20mm, 15mm, 10mm]
image:
caption:
align: inherit
font-style: normal
caption:
font-style: normal
admonition:
icon:
question:
name: fa-question
stroke_color: 000000
size: 24
answer:
name: fa-lightbulb
stroke_color: 000000
size: 24

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

@ -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,19 +0,0 @@
---
title: "LaTeX: русский язык в выходном PDF"
category: LaTeX
tags: LaTeX, текст, PDF
summary:
...
Для поиска в файле 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
```
----

46
wiki/Linux/CUPS.adoc Normal file
View File

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

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

@ -0,0 +1,44 @@
= Настройка Redis
:category: Linux
:tags: Linux, Redis,
Создать файл `/etc/sysctl.d/98-redis.conf`:
[source,text]
----
net.core.somaxconn=65535
vm.overcommit_memory=1
----
Перезагрузить систему или выполнить команду:
[source,sh]
----
sudo sysctl -p
----
Создать файл `/etc/systemd/system/disable-transparent-huge-pages.service`:
[source,text]
----
[Unit]
Description=Disable Transparent Huge Pages (THP)
DefaultDependencies=no
After=sysinit.target local-fs.target
Before=mongod.service redis.service redis-server.service
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'echo never | tee /sys/kernel/mm/transparent_hugepage/enabled > /dev/null'
[Install]
WantedBy=basic.target
----
Разрешить автоматический запуск при загрузке системы:
[source,sh]
----
sudo systemctl enable disable-transparent-huge-pages.service
----

View File

@ -0,0 +1,29 @@
= Настройка параметров локальной сети
:category: Linux
:tags: Linux, сеть, ethernet
Создать файл `/etc/sysctl.d/98-network.conf`:
[source,text]
----
net.core.rmem_default=262144
net.core.wmem_default=262144
net.core.rmem_max=33554432
net.core.wmem_max=33554432
net.ipv4.tcp_rmem = 4096 262144 33554432
net.ipv4.tcp_wmem = 4096 262144 33554432
net.ipv4.tcp_mem = 4096 262144 33554432
net.core.netdev_max_backlog = 16384
net.ipv4.ipfrag_high_threshold = 8388608
----
Перезагрузить систему или выполнить команду:
[source,sh]
----
sudo sysctl -p
----

View File

@ -1,16 +1,14 @@
---
title: "Сервер времени NTP в локальной сети"
category: Linux
tags: Linux, NTP, время
summary:
...
= Сервер времени NTP в локальной сети
:category: Linux
:tags: Linux, NTP, время,
Если в локальной сети необходимо синхронизировать время, не имея
авторитетного источника времени, то можно использовать локальные
часы сервера в качестве базовых. В этом случае файл настройки
`/etc/ntp.conf` на сервере будет выглядеть так:
авторитетного источника времени, то можно использовать локальные часы
сервера в качестве базовых. В этом случае файл настройки `/etc/ntp.conf`
на сервере `192.168.0.1` будет выглядеть так:
```
[source,text]
----
driftfile /var/lib/ntp/ntp.drift
logfile /var/log/ntp.log
tinker panic 0
@ -19,12 +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`,
и получающем время от сервера `192.168.0.1`, имеет вид:
Файл `/etc/ntp.conf` на клиенте из подсети `192.168.0.0/24` имеет вид:
```
[source,text]
----
driftfile /var/lib/ntp/ntp.drift
logfile /var/log/ntp.log
tinker panic 0
@ -33,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,11 +0,0 @@
---
title: "Linux: полезные ссылки"
category: Linux
tags: Linux, ссылки
summary:
...
* [Параметры загрузки ядра](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,align="center"]
.Экран 2
image::oo-shutup/2.jpg[2,align="center"]
.Экран 3
image::oo-shutup/3.jpg[3,align="center"]
.Экран 4
image::oo-shutup/4.jpg[4,align="center"]
.Экран 5
image::oo-shutup/5.jpg[5,align="center"]

View File

@ -1,706 +0,0 @@
---
title: "CMake: управление проектом"
category: Программирование
tags: программирование, cmake
summary: ""
CSS: table-100.css
toc: yes
monofontoptions:
- Scale=0.6
...
[TOC]
### Полезные ссылки
* [Каталог ссылок](https://github.com/onqtam/awesome-cmake)
* [CGold: The Hitchhikers Guide to the CMake](https://cgold.readthedocs.io/en/latest/index.html)
### Структура каталогов проекта
Файлы проекта и результаты компиляции размещаются в каталогах:
```
└── cmex
├── _build
│ ├── Debug
│ └── Release
├── .git
├── cmake
│ ├── cmlib
│ ├── etc
│ ├── find
│ └── generators
├── doc
├── files
│ ├── etc
│ ├── share
│ └── var
├── l10n
├── src
│ ├── app
│ └── 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` | Дополнительные утилиты
Каталог `_build` создаётся, чтобы избежать попадания получаемых во время
сборки файлов в иерархию основного проекта.
Запись результатов сборки проекта внутрь иерархии каталогов с исходными текстами
приводит к засорению формируемыми на этапе сборки файлами, которые затрудняют
разработку, поиск в оригинальных файлах и мешают ориентироваться в проекте.
При работе с несколькими типами сборки, например, отладка и выпуск, появляется
необходимость корректного полного удаления результатов предыдущего тип сборки.
### Начало проекта
В каталоге `cmex` нужно создать файл `CMakeLists.txt`:
```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/).
В каталог `cmake/cmlib` установить субмодуль CMLib, содержащий функции для CMake:
```
git submodule add ssh://git@gitlab-server/root/cmlib cmake/cmlib
```
и подключить в файле `CMakeLists.txt`:
```cmake
# В каталоге cmake/cmlib находятся файлы с библиотечными функциями
if(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/cmake/cmlib)
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/cmlib)
else()
message(FATAL_ERROR "CMake library directory does not exist")
endif()
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/find)
include(CMLibCommon)
```
В файле `cmake/etc/organization.txt` записать название
организации, которой принадлежит проект:
```
ORG, Inc.
```
В файле `cmake/etc/cpack_ignore.txt` перечислить шаблоны
для исключения из архива, создаваемого целью `dist`. Например:
```
cmake/lib/.git$
.git$
files/var
CMakeLists.txt.user
~$
\\\\..*\\\\.bak$
\\\\..*\\\\.tmp$
\\\\..*\\\\.swp$
```
Чтобы проверить корректность файла `CMakeLists.txt`, нужно создать каталог
`_build` в каталоге `cmex`, перейти в него и выполнить команды:
```sh
cmake ..
make
```
### Поиск системных библиотек
Системные библиотеки можно искать с помощью программы `pkgconfig`,
которая хранит базу данных параметров, включающую пути к заголовочным
файлами и перечни библиотек, необходимых для компоновки.
Сначала производится наличие модуля `PkgConfig`, в котором определена
функция `pkg_check_modules`, которая и осуществляет поиск. Например,
для поиска библиотек `gsl`, `fftw3` и `udev` можно написать:
```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`
может возвращать дополнительные значения, например, пути к исполняемым файлам.
```cmake
# Поиск с помощью функции find_package
find_package(LibXml2)
find_package(CURL)
```
Если для библиотеки нет модуля, выполняющего её поиск, то можно
произвести поиск с помощью функции `find_library`. Например,
```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
присутствует функция `cmlib_config_hpp_generate()`, создающая файл
`${CMAKE_BUILD_DIR}/include/config.hpp`, в который записывается
информация о имени и версии проекта, дате и типе сборки.
```cmake
# Автоматически генерируемый заголовочный файл
cmlib_config_hpp_generate()
```
### Базовая библиотека
В файле `cmex/CMakeLists.txt` должна быть строка, включающая
поиск файла `CMakeLists.txt` в подкаталоге `src/lib`:
```cmake
add_subdirectory(src/libcmex)
```
В каталоге `cmex/src/libcmex` нужно создать файл `cmex.hpp`:
```cpp
#ifndef LIBCMEX_CMEX_HPP_
#define LIBCMEX_CMEX_HPP_
#include <stdint.h>
int32_t cmex_init(int32_t i);
#endif // LIBCMEX_CMEX_HPP_
```
файл `cmex.cpp`:
```cpp
#include "cmex.hpp"
int32_t cmex_init(int32_t i = 0) {
return i;
}
```
и файл `CMakeLists.txt`:
```cmake
# Название основной цели и имя библиотеки в текущем каталоге
set(current_target cmex)
# Список файлов исходных текстов
set(current_target_sources
cmex.cpp
)
# Список заголовочных файлов (используется для установки)
set(current_target_headers
cmex.hpp
)
add_common_library(TARGET ${current_target} SOURCES ${current_target_sources})
common_target_properties(${current_target})
# Цель, используемая только для установки заголовочных файлов, без компиляции проекта
add_custom_target(${current_target}-install-headers
COMMAND "${CMAKE_COMMAND}"
-DCMAKE_INSTALL_COMPONENT=headers -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
# Правила для установки
install(TARGETS ${current_target}_static ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(BUILD_SHARED_LIBS)
install(TARGETS ${current_target}_shared LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
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`:
```cmake
add_subdirectory(src/cmex)
```
В каталоге `cmex/src/cmex` нужно создать файл `main.cpp`:
```cpp
#include "compiler_features.hpp"
#include "config.hpp"
#include <iostream>
#include "cmex.hpp"
int main(int argc, char **argv) {
std::cout << CMEX_COMPILER_VERSION_MAJOR << std::endl; // Значение из compiler_features.hpp
std::cout << BUILD_TYPE << std::endl; // Значение из config.hpp
std::cout << CMEX_VERSION_STR << std::endl; // Значение из config.hpp
std::cout << cmex_init(4) << std::endl; // Функция из внутренней библиотеки
return 0;
}
```
и файл `CMakeLists.txt`:
```cmake
# Название основной цели в текущем каталоге
set(current_target cmex_app)
# Список файлов исходных текстов
set(current_target_sources
main.cpp
)
# Цель для создания исполняемого файла
add_executable(${current_target} ${current_target_sources})
common_target_properties(${current_target})
# Зависимость от библиотеки из текущего проекта
add_dependencies(${current_target} cmex)
# Добавление внутреннего каталога src/libcmex к списку путей для поиска заголовочных файлов
target_include_directories(${current_target} PUBLIC
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/src/libcmex>)
# Имя выходного файла для цели (параметр OUTPUT_NAME)
set_target_properties(${current_target}
PROPERTIES
OUTPUT_NAME cmex
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}
)
# Путь поиска библиотек внутри проекта
link_directories(${CMAKE_INSTALL_LIBDIR})
# Сначала внутренние статические библиотеки
target_link_libraries(${current_target} cmex_static)
# Правила для установки
install(TARGETS ${current_target} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
```
### Подключение внешнего проекта
В каталоге `cmex/thirdparty` нужно создать каталог `cmext` с проектом,
состоящим из файлов `cmext.hpp`:
```c
#ifndef CMEXT_CMEXT_HPP_
#define CMEXT_CMEXT_HPP_
#include <stdint.h>
int32_t cmext_init(int32_t i);
#endif
```
`cmext.cpp`:
```c
#include "cmext.hpp"
int32_t cmext_init(int32_t i = 0) {
return i;
}
```
и `CMakeLists.txt`:
```cmake
cmake_minimum_required(VERSION 3.3)
project(cmext)
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
# Подключение внешних проектов
include(ExternalProject)
ExternalProject_Add(cmext
EXCLUDE_FROM_ALL TRUE
SOURCE_DIR ${CMAKE_SOURCE_DIR}/thirdparty/libcmext
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`
для определения зависимостей.
В файле `cmex/src/cmex/CMakeLists.txt` нужно подключить внешний проект `cmext`:
```cmake
# Зависимость от библиотеки из внешнего проекта проекта
add_dependencies(${current_target} cmext)
```
```cmake
# Добавление каталога, в который устанавливаются заголовочные файлы от внешнего
# проекта cmext, к списку путей для поиска заголовочных файлов
target_include_directories(${current_target} PUBLIC
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/include/cmext>)
```
```cmake
# Библиотека из внешнего проекта cmext
target_link_libraries(${current_target} ${CMAKE_BINARY_DIR}/lib/libcmext.a)
```
Для проверки работоспособности в файле `cmex/src/cmex/main.cpp` нужно вызвать
функцию `cmext_init` из библиотеки, предоставляемой внешним проектом.
Например:
```cpp
#include "compiler_features.hpp"
#include "config.hpp"
#include <iostream>
#include <cmext/cmext.hpp>
#include "cmex.hpp"
QTextStream& qStdOut()
{
static QTextStream ts(stdout);
return ts;
}
int main(int argc, char **argv) {
// Значение из compiler_features.hpp
qStdOut() << QObject::tr("Compiler version: ") << CMEX_COMPILER_VERSION_MAJOR << endl;
// Значение из config.hpp
qStdOut() << QObject::tr("Project version: ") << CMEX_VERSION_STR << endl;
// Значение из config.hpp
qStdOut() << QObject::tr("Build type: ") << BUILD_TYPE << endl;
// Функция из внутренней библиотеки
qStdOut() << QObject::tr("libcmex function call: ") << cmex_init(4) << endl;
// Функция из внешней библиотеки
qStdOut() << QObject::tr("libcmext function call: ") << cmext_init(9) << endl;
return 0;
}
```
### Qt5
Для поиска необходимых компонентов Qt5 нужно в файл `cmex/CMakeLists.txt`
добавить строки:
```cmake
find_package(Qt5 COMPONENTS Core Network Gui Widgets DBus Concurrent Sql REQUIRED)
```
Библиотека CMLib автоматически подключает вызов препроцессора `moc`
и компилятора ресурсов `rcc`, если цель использует модуль `Core`, и
вызывает компилятор файлов описания интерфейса, если цель использует
модуль `Widgets`.
### Консольное приложение
В файл `cmex/src/cmex/CMakeLists.txt` добавить строки:
```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`
нужно заменить на:
```cpp
#include "compiler_features.hpp"
#include "config.hpp"
#include <QtCore>
#include <iostream>
#include <cmext/cmext.hpp>
#include "cmex.hpp"
QTextStream& qStdOut()
{
static QTextStream ts(stdout);
return ts;
}
int main(int argc, char **argv) {
QCoreApplication app(argc, argv);
QTranslator translator;
if (translator.load(QLocale(), "cmex_app", QLatin1String("_"), QLatin1String(":/qm")))
{
app.installTranslator(&translator);
}
// Значение из compiler_features.hpp
qStdOut() << QObject::tr("Compiler version: ") << CMEX_COMPILER_VERSION_MAJOR << endl;
// Значение из config.hpp
qStdOut() << QObject::tr("Project version: ") << CMEX_VERSION_STR << endl;
// Значение из config.hpp
qStdOut() << QObject::tr("Build type: ") << BUILD_TYPE << endl;
// Функция из внутренней библиотеки
qStdOut() << QObject::tr("libcmex function call: ") << cmex_init(4) << endl;
// Функция из внешней библиотеки
qStdOut() << QObject::tr("libcmext function call: ") << cmext_init(9) << endl;
return 0;
}
```
После сборки проекта в каталоге `cmex/l10n` появится файл `cmex_app_ru_RU.ts`,
в котором нужно отредактировать переводы с помощью программы `linguist`.
После сохранения переводов проект нужно пересобрать, файл переводов в
скопилированном виде будет встроен в исполняемый файл `cmex`, а доступ
к нему будет осуществляться с помощью кода:
```cpp
if (translator.load(QLocale(), "cmex_app", QLatin1String("_"), QLatin1String(":/qm")))
{
app.installTranslator(&translator);
}
```
### Графическое приложение
Для создания минимального графического приложения нужно создать
файл описания интерфейса `cmex/src/cmex/my_main_window.ui`:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MyMainWindow</class>
<widget class="QMainWindow" name="MyMainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>678</width>
<height>415</height>
</rect>
</property>
<property name="windowTitle">
<string>Main Window</string>
</property>
<widget class="QWidget" name="centralwidget"/>
</widget>
<resources/>
<connections/>
</ui>
```
заголовочный файл `cmex/src/cmex/my_main_window.hpp`:
```cpp
#ifndef CMEX_MY_MAIN_WINDOW_HPP_
#define CMEX_MY_MAIN_WINDOW_HPP_
#include <QWidget>
#include "ui_my_main_window.h"
class MyMainWindow : public QWidget, private Ui::MyMainWindow {
Q_OBJECT
public:
MyMainWindow(QWidget* parent = 0);
virtual ~MyMainWindow();
};
#endif /* CMEX_MY_MAIN_WINDOW_HPP_ */
```
и файл с реализацией конструктора и деструктора `cmex/src/cmex/my_main_window.cpp`:
```cpp
#include "my_main_window.hpp"
MyMainWindow::MyMainWindow(QWidget* parent) {
}
MyMainWindow::~MyMainWindow() {
}
```
Для отображения графического окна нужно заменить файл
`cmex/src/cmex/main.cpp` на:
```cpp
#include "compiler_features.hpp"
#include "config.hpp"
#include <QtCore>
#include <QtWidgets>
#include <iostream>
#include <cmext/cmext.hpp>
#include "cmex.hpp"
#include "my_main_window.hpp"
QTextStream& qStdOut()
{
static QTextStream ts(stdout);
return ts;
}
int main(int argc, char **argv) {
QApplication app(argc, argv);
QTranslator translator;
if (translator.load(QLocale(), "cmex_app", QLatin1String("_"), QLatin1String(":/qm")))
{
app.installTranslator(&translator);
}
// Значение из compiler_features.hpp
qStdOut() << QObject::tr("Compiler version: ") << CMEX_COMPILER_VERSION_MAJOR << endl;
// Значение из config.hpp
qStdOut() << QObject::tr("Project version: ") << CMEX_VERSION_STR << endl;
// Значение из config.hpp
qStdOut() << QObject::tr("Build type: ") << BUILD_TYPE << endl;
// Функция из внутренней библиотеки
qStdOut() << QObject::tr("libcmex function call: ") << cmex_init(4) << endl;
// Функция из внешней библиотеки
qStdOut() << QObject::tr("libcmext function call: ") << cmext_init(9) << endl;
MyMainWindow* mmw = new MyMainWindow();
mmw->show();
return app.exec();
}
```
В файле `cmex/src/cmex/CMakeLists.txt` добавить новые файлы
к списку файлов, используемых для компиляции:
```cmake
set(current_target_sources
main.cpp
my_main_window.cpp
)
set(current_target_uis
my_main_window.ui
)
```
```cmake
# Цель для создания исполняемого файла
add_executable(${current_target} ${current_target_sources} ${current_target_uis})
```
и добавить строки для подключения графических библиотек Qt5
и соответствующих им заголовочных файлов:
```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`
и снова скомпилировать проект.
### Удаление установленных файлов
В библиотеку CMLib добавлена цель `uninstall`, позволяющая удалить
файлы, перечисленные в файле `${CMAKE_BUILD_DIR}/install_manifest.txt`.
### Архивирование проекта
Стандарный модуль `CPack` осуществляет архивирование проекта. В файле
`cproj/cmake/etc/cpack_ignore.txt` определён список типовых масок файлов для
исключения из архива:
```
.git$
files/var
CMakeLists.txt.user
~$
\\\\..*\\\\.bak$
\\\\..*\\\\.tmp$
\\\\..*\\\\.swp$
```
По умолчанию цель для упаковки проекта называется `package_source`.
В библиотеке CMLib определены значения основных параметров, а также
дополнительная цель `dist`.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,69 @@
= 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`.
. От суперпользователя установить в каталог `/opt/intel` командой
`sudo ./install.sh -s silent.cfg`.
. Добавить полномочия для сбора статистики:
[source,sh]
----
sudo setcap cap_sys_ptrace=eip /opt/intel/vtune_profiler/bin64/vtune
sudo setcap cap_sys_ptrace=eip /opt/intel/vtune_profiler/bin64/amplxe-perf
----
[arabic, start=6]
. Создать образ:
`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_profiler/amplxe-vars.sh
----
[arabic, start=10]
. Создать файл `/etc/sysctl.d/97-vtune.conf`:
[source,text]
----
kernel.kptr_restrict=0
kernel.perf_event_paranoid=0
kernel.yama.ptrace_scope=0
----
[arabic, start=11]
. Прочитать его: `sysctl -p /etc/sysctl.d/97-vtune.conf`
. Создать группу `vtune` и добавить в неё пользователя:
[source,sh]
----
groupadd vtune
usermod -a -G vtune user
----
[arabic, start=13]
. Установить модули ядра для упрощения доступа к отладочной информации:
[source,sh]
----
sudo apt-get install dkms build-essential linux-headers-generic
sudo dpkg -i /opt/intel/vtune-dkms*deb
----

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,129 @@
= Настройка Qt Creator
:title-separator: {sp}|
:category: Linux/Программы
:tags: Linux, Qt, Qt Creator, C++,
:toc:
:icons: font
include::{l10ndir}/{lang}.adoc[]
Перед настройкой Qt Creator желательно установить пакеты для разработки
и выполнить дополнительные настройки:
[source,sh]
----
sudo apt-get install git ninja-build cmake uncrustify dos2unix doxygen
sudo apt-get install clazy clang-tidy build-essential qt5-default
git clone https://git.246060.ru/f1x1t/uncrustify-config ~/.config/uncrustify
----
<<<
== Плагины
[.text-center]
.menu:Справка[О модулях] (часть 1)
image::qtcreator-setup/qtcreator21.png[qtcreator21,pdfwidth=70%,scaledwidth=90%,align="center"]
{empty} +
[.text-center]
.menu:Справка[О модулях] (часть 2)
image::qtcreator-setup/qtcreator22.png[qtcreator22,pdfwidth=70%,scaledwidth=90%,align="center"]
{empty} +
[.text-center]
.menu:Справка[О модулях] (часть 3)
image::qtcreator-setup/qtcreator23.png[qtcreator23,pdfwidth=70%,scaledwidth=90%,align="center"]
{empty} +
[.text-center]
.menu:Справка[О модулях] (часть 4)
image::qtcreator-setup/qtcreator24.png[qtcreator24,pdfwidth=70%,scaledwidth=90%,align="center"]
{empty} +
== Комплекты
[.text-center]
.menu:Инструменты[Параметры > Комплекты > Комплекты]
image::qtcreator-setup/qtcreator34.png[qtcreator34,pdfwidth=80%,scaledwidth=80%,align="center"]
{empty} +
[.text-center]
.menu:Инструменты[Параметры > Комплекты > Комплекты > Генератор CMake > Изменить]
image::qtcreator-setup/qtcreator35.png[qtcreator35,align="center"]
{empty} +
<<<
== Среда
[.text-center]
.menu:Инструменты[Параметры > Среда > Система]
image::qtcreator-setup/qtcreator41.png[qtcreator41,pdfwidth=80%,scaledwidth=80%,align="center"]
{empty} +
== Редактор
[.text-center]
.menu:Инструменты[Параметры > Текстовый редактор > Поведение]
image::qtcreator-setup/qtcreator42.png[qtcreator42,pdfwidth=80%,scaledwidth=80%,align="center"]
{empty} +
== C++
[.text-center]
.menu:Инструменты[Параметры > С++ > Именование файлов]
image::qtcreator-setup/qtcreator51.png[qtcreator51,pdfwidth=78%,scaledwidth=78%,align="center"]
{empty} +
== Стилизатор
[.text-center]
.menu:Инструменты[Параметры > Стилизатор > Uncrustify]
image::qtcreator-setup/qtcreator55.png[qtcreator55,pdfwidth=78%,scaledwidth=78%,align="center"]
{empty} +
== Сборка и запуск
[.text-center]
.menu:Инструменты[Параметры > Сборка и запуск > Основное]
image::qtcreator-setup/qtcreator61.png[qtcreator61,pdfwidth=78%,scaledwidth=80%,align="center"]
{empty} +
<<<
== To-Do
[.text-center]
.menu:Инструменты[Параметры > To-Do]
image::qtcreator-setup/qtcreator67.png[qtcreator67,pdfwidth=78%,scaledwidth=80%,align="center"]
{empty} +
== Импорт проекта на CMake
[.text-center]
.menu:Импорт проекта[Настроить проект]
image::qtcreator-setup/qtcreator74.png[qtcreator74,pdfwidth=80%,scaledwidth=80%,align="center"]
{empty} +
== Сборка
[.text-center]
.menu:Проект[Настройки сборки]
image::qtcreator-setup/qtcreator81.png[qtcreator81,pdfwidth=80%,scaledwidth=80%,align="center"]

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,269 @@
= Программный проект и иерархия каталогов
:title-separator: {sp}|
:category: Программирование
:tags: Linux, файлы, каталоги, программирование, cmake
:toc:
include::{l10ndir}/{lang}.adoc[]
Для операционных систем типа Linux принят стандарт
https://ru.wikipedia.org/wiki/FHS[FHS] («стандарт иерархии файловой
системы»), унифицирующий местонахождение файлов и каталогов с общим
назначением в файловой системе. Полная текущая версия стандарта
находится http://refspecs.linuxfoundation.org/fhs.shtml[здесь].
== Типы расположения проекта
В соответствии с данным стандартом, а также принятыми в ведущих
дистрибутивах правилами размещения исполняемых файлов в каталогах
пользователей, можно выделить следующие типы расположения:
* системная иерархия в каталоге `/usr` используется для установки
бинарных пакетов для данного дистрибутива;
* системная иерархия в каталоге `/usr/local` используется для установки
программного обеспечения системным администратором без использования
пакетов (не рекомендуется для использования из-за проблем поддержки
в актуальном состоянии);
* системная иерархия в каталоге `/opt` используется для установки
стороннего программного обеспечения. В рамках данной иерархии
предполагается, что каждый программный продукт располагается в
собственном каталоге. При таком типе сборки обычно используются
дополнительные методы (статическая компоновка, включение в состав
пакета своего набора динамических библиотек) для обеспечения работы
пакета в операционных системам с отличающимся составом библиотек
и другим циклом обновления;
* системная иерархия в домашнем каталоге пользователя не имеет
определённого стандарта, обычно производители дистрибутивов
предлагают использовать для исполняемых файлов каталоги
`$HOME/bin` или `$HOME/.local/bin`.
Система автоматизации сборки программного обеспечения https://cmake.org[CMake]
позволяет организовать окружение подобное перечисленным выше.
На этапе сборки проекта можно создать структуру каталогов,
которая будет отвечать требованиям по логическому разделению
файлов на исполняемые, заголовочные, библиотеки, файлы настроек и т.д.
== Автоматическая адаптация к текущему окружению
Для обеспечения единообразной работы вне зависимости от варианта
иерархии каталогов, в которой находится исполняемый файл, можно
выполнять автоматическую настройку на работу в текущем окружении.
В библиотеке https://git.246060.ru/f1x1t/myxlib[myxlib] реализован
класс, который анализирует расположение и окружение исполняемого
файла и предоставляет методы для получения имён каталогов,
соответствующих текущему окружению. Названия методов и описания
возвращаемых значений приведены в таблице.
.Имена методов и описания
[cols="2m,4",options="header"]
|===
| Метод | Описание
| homeDirectory() | Полный путь к домашнему каталогу текущего пользователя
| tempDirectory() | Полный путь к каталогу с временными файлами
| userConfigDirectory() | Полный путь к пользовательскому каталогу с файлами настройки
| userConstDataDirectory() | Полный путь к пользовательскому каталогу с неизменяемыми файлами
| userVarDataDirectory() | Полный путь к пользовательскому каталогу с изменяемыми файлами
| userLogDirectory() | Полный путь к пользовательскому каталогу с журналами работы
| executableFilePath() | Полный путь к исполняемому файлу
| systemConfigDirectory() | Полный путь к системному каталогу с файлами настройки
| systemConstDataDirectory() | Полный путь к системному каталогу с неизменяемыми файлами
| systemVarDataDirectory() | Полный путь к системному каталогу с изменяемыми файлами
| systemLogDirectory() | Полный путь к системному каталогу с журналами работы
| executableFileDirectory() | Полный путь к каталогу с исполняемым файлом
| executableFileName() | Имя исполняемого файла
| projectName() | Имя подкаталога для проекта
|===
Пример использования:
[source,cpp]
----
#include <myx/filesystem/paths.hpp>
namespace MF = myx::filesystem;
MF::Paths& paths = MF::Paths::instance();
paths.init();
qDebug() << paths.systemConstDataDirectory().path();
----
== Правила выбора типа окружения
Класс `myx::filesystem::Paths` реализован в виде синглтона,
чтобы повторно не выполнять проверку окружения в разных частях программы.
Сначала определяются имена пользовательского и временного каталогов с
помощью вызовов функций https://doc.qt.io/qt-5/qdir.html#homePath[`QDir::homePath`]
и https://doc.qt.io/qt-5/qdir.html#tempPath[`QDir::tempPath`], затем
имена пользовательских каталогов для настроек, постоянных и изменяемых
данных и журналов. Эти значения не зависят от расположения исполняемого файла,
а определяются в соответствии со значениям переменных окружения `HOME`,
`TMPDIR`, `XDG_CONFIG_HOME` и `XDG_DATA_HOME`, либо устанавливаются значения,
принятые в стандартах. Пример имён каталогов для пользователя `user`,
названия организации `org`, названия выполняемой работы `theme` и проекта
`project` приведён в таблице.
.Стандартные каталоги для текущего пользователя
[cols="4,4m,6m",options="header"]
|===
| Назначение каталога | Метод | Значение
| Домашний каталог | homeDirectory() | /home/user
| Временные файлы | tempDirectory() | /tmp
| Файлы настройки | userConfigDirectory() | /home/user/.config/org-theme/project
| Неизменяемые файлы | userConstDataDirectory() | /home/user/.local/share/org-theme/project/share
| Изменяемые файлы | userVarDataDirectory() | /home/user/.local/share/org-theme/project/var
| Журналы работы | userLogDirectory() | /home/user/.local/share/org-theme/project/log
|===
=== Общая проверка
Для определения типа текущего окружения используется полный путь
к исполняемому файлу, если он находится в каталоге `bin`, то выполняются
проверки работы в одной из возможных вариантов иерархий,
иначе делается заключение о том, что файлы всех типов находятся
в одном каталоге с исполняемым и дальнейшие проверки не выполняются.
IMPORTANT: При проверке типов иерархии всегда проверяется наличие
всех необходимых каталогов, при отсутствии хотя бы одного будет
принято решение, что файлы всех типов находятся в одном каталоге
с исполняемым.
=== Проверка на работу в иерархии `/opt`
Если полный путь к исполняемому файлу начинается с `/opt` и
содержит в себе название текущего проекта, например
`/opt/org-theme/project/bin/application`, то выполняется проверка
на наличие сопутствующих системных каталогов. Если они присутствуют,
то принимается решение, что окружение в иерархии `/opt` сформировано правильно,
иначе делается заключение о том, что файлы всех типов находятся
в одном каталоге с исполняемым и дальнейшие проверки не выполняются.
Пример правильной структуры каталогов для данной иерархии приведён в таблице.
.Каталоги в иерархии `/opt`
[cols="4,4m,5m",options="header"]
|===
| Назначение файла / каталога | Метод | Значение
| Исполняемый файл | executableFilePath() | /opt/org-theme/project/bin/application
| Файлы настройки | systemConfigDirectory() | /opt/org-theme/project/etc
| Неизменяемые файлы | systemConstDataDirectory() | /opt/org-theme/project/share
| Изменяемые файлы | systemVarDataDirectory() | /opt/org-theme/project/var
| Журналы работы | systemLogDirectory() | /opt/org-theme/project/log
|===
=== Проверка на работу в иерархии `/usr/local`
Если полный путь к исполняемому файлу начинается с `/usr/local`,
например `/usr/local/bin/application`, то выполняется проверка
на наличие сопутствующих системных каталогов. Если они присутствуют,
то принимается решение, что окружение в иерархии `/usr/local` сформировано правильно,
иначе делается заключение о том, что файлы всех типов находятся
в одном каталоге с исполняемым и дальнейшие проверки не выполняются.
Пример правильной структуры каталогов для данной иерархии приведён в таблице.
.Каталоги в иерархии `/usr/local`
[cols="4,4m,5m",options="header"]
|===
| Назначение файла / каталога | Метод | Значение
| Исполняемый файл | executableFilePath() | /usr/local/bin/application
| Файлы настройки | systemConfigDirectory() | /usr/local/etc/project
| Неизменяемые файлы | systemConstDataDirectory() | /usr/local/share/project
| Изменяемые файлы | systemVarDataDirectory() | /var/lib/project
| Журналы работы | systemLogDirectory() | /var/log/project
|===
=== Проверка на работу в иерархии `/usr`
Если полный путь к исполняемому файлу начинается с `/usr`,
например `/usr/bin/application`, то выполняется проверка
на наличие сопутствующих системных каталогов. Если они присутствуют,
то принимается решение, что окружение в иерархии `/usr` сформировано правильно,
иначе делается заключение о том, что файлы всех типов находятся
в одном каталоге с исполняемым и дальнейшие проверки не выполняются.
Пример правильной структуры каталогов для данной иерархии приведён в таблице.
.Каталоги в иерархии `/usr`
[cols="4,4m,5m",options="header"]
|===
| Назначение файла / каталога | Метод | Значение
| Исполняемый файл | executableFilePath() | /usr/bin/application
| Файлы настройки | systemConfigDirectory() | /etc/project
| Неизменяемые файлы | systemConstDataDirectory() | /usr/share/project
| Изменяемые файлы | systemVarDataDirectory() | /var/lib/project
| Журналы работы | systemLogDirectory() | /var/log/project
|===
=== Проверка на работу в домашнем каталоге
Если полный путь к исполняемому файлу начинается с `/home/user/bin` или
`/home/user/.local/bin`, например `/home/user/bin/application`, то выполняется
проверка на наличие сопутствующих системных каталогов. Если они присутствуют,
то принимается решение, что окружение в домашнем каталоге сформировано правильно,
иначе делается заключение о том, что файлы всех типов находятся
в одном каталоге с исполняемым и дальнейшие проверки не выполняются.
Пример правильной структуры каталогов для данной иерархии приведён в таблице.
.Каталоги при работе в домашнем каталоге
[cols="4,4m,6m",options="header"]
|===
| Назначение файла / каталога | Метод | Значение
| Исполняемый файл | executableFilePath() | /home/user/bin/application
| Файлы настройки | systemConfigDirectory() | /home/user/.config/org-theme/project
| Неизменяемые файлы | systemConstDataDirectory() | /home/user/.local/share/org-theme/project/share
| Изменяемые файлы | systemVarDataDirectory() | /home/user/.local/share/org-theme/project/var
| Журналы работы | systemLogDirectory() | /home/user/.local/share/org-theme/project/log
|===
=== Проверка на работу в окружении для разработки
Если исполняемый файл находится в каталоге `bin` и при этом окружение не совпадает
ни с одним из перечисленных выше, то делается предположение, что исполняемый файл
запускается из окружения, сформированного системой управления проектом, и в данный
момент идёт разработка (отладка) приложения. В этом случае целесообразно считать
системными каталогами те, которые находятся внутри иерархии каталогов программного
проекта. Если присутствуют каталоги, созданные системой управления проекта,
то принимается решение, что окружение сформировано правильно,
иначе делается заключение о том, что файлы всех типов находятся
в одном каталоге с исполняемым и на этом проверки заканчиваются.
Пример правильной структуры каталогов для данной иерархии приведён в таблице.
.Каталоги при работе в окружении для разработки
[cols="4,4m,6m",options="header"]
|===
| Назначение файла / каталога | Метод | Значение
| Исполняемый файл | executableFilePath() | /home/user/work/project/_build/debug/bin/application
| Файлы настройки | systemConfigDirectory() | /home/user/work/project/_build/debug/etc
| Неизменяемые файлы | systemConstDataDirectory() | /home/user/work/project/_build/debug/share
| Изменяемые файлы | systemVarDataDirectory() | /home/user/work/project/_build/debug/var
| Журналы работы | systemLogDirectory() | /home/user/work/project/_build/debug/log
|===
=== Расположение в одном каталоге
Если в ходе перечисленных выше проверок не удалось найти правильно
сформированное окружение, то применяется настройка по умолчанию,
которая соответствует ситуации, когда все типы файлов расположены
в одном каталоге с исполняемым файлом. Пример для такого случая приведён в таблице.
.Каталоги в неопределённой иерархии
[cols="4,4m,6m",options="header"]
|===
| Назначение файла / каталога | Метод | Значение
| Исполняемый файл | executableFilePath() | /home/user/work/project/application
| Файлы настройки | systemConfigDirectory() | /home/user/work/project
| Неизменяемые файлы | systemConstDataDirectory() | /home/user/work/project
| Изменяемые файлы | systemVarDataDirectory() | /home/user/work/project
| Журналы работы | systemLogDirectory() | /home/user/work/project
|===

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,65 +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 -- yourapp
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
## 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

@ -0,0 +1,150 @@
= Статический анализ кода
:category: Программирование
:tags: программирование, отладка, cppcheck, iwyu, clang-tidy, cpplint, clazy,
== Общее описание
Ниже приведены утилиты для проверки кода на C++ и примеры их настройки и
использования совместно с https://cmake.org/[CMake].
=== http://clang.llvm.org/extra/clang-tidy/[clang-tidy]
Установка:
[source,sh]
----
sudo apt-get install clang-tidy-10
----
Использование:
[source,sh]
----
cmake "-DCMAKE_CXX_CLANG_TIDY=/usr/bin/clang-tidy-10" path/to/source
----
В каталоге проекта нужно создать файл `.clang-tidy` в формате YAML со
списком выполняемых проверок. Например:
[source,yaml]
----
---
Checks: '-*,
bugprone-*,
clang-analyzer-*,
cppcoreguidelines-*,
google-*,
llvm-*,
misc-*,
modernize-*,
readability-*,
performance-*,
portability-*,
-cppcoreguidelines-owning-memory,
-cppcoreguidelines-avoid-magic-numbers,
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
-readability-magic-numbers,
-readability-else-after-return,
-modernize-use-trailing-return-type,
-modernize-avoid-c-arrays,
-performance-no-automatic-move,
'
CheckOptions:
- key: readability-identifier-naming.ClassCase
value: CamelCase
- key: readability-identifier-naming.ClassMemberCase
value: camelBack
...
----
Пример файла `.clang-tidy`, в котором перечислены все правила для
проверки именования идентификаторов приведён
https://git.246060.ru/f1x1t/clang-tidy-readability-identifier-naming[здесь].
=== CppCheck
Установка:
[source,sh]
----
sudo apt-get install cppcheck
----
Использование:
[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.
=== CppLint
Установка:
[source,sh]
----
sudo apt-get install python3-cpplint
----
Использование:
[source,sh]
----
cmake "-DCMAKE_CXX_CPPLINT=/usr/bin/cpplint;--linelength=79" path/to/source
----
[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.
=== IWYU
Установка:
[source,sh]
----
sudo apt-get install iwyu
----
Использование:
[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.
=== LWYU
[source,sh]
----
cmake -DCMAKE_LINK_WHAT_YOU_USE=TRUE ..
----
=== Clazy
Установка:
[source,sh]
----
sudo apt-get install clazy clang-9
----
Использование:
[source,sh]
----
CLAZY_CHECKS=level2 cmake -DCMAKE_CXX_COMPILER=clazy ..
CLANGXX=clang++-9 make
----

View File

@ -0,0 +1,44 @@
= Разные вопросы и ответы
:title-separator: {sp}|
:category: Linux/Программы
:tags: Linux, Qt, Qt Creator, C++,
:toc:
:icons: font
include::{l10ndir}/{lang}.adoc[]
[QUESTION]
====
[float]
==== Проект на CMake перестал настраиваться.
Сообщения вида:
----
Не удалось разобрать проект CMake: потеряно соединение с сервером CMake.
----
====
[ANSWER]
====
. Закрыть проект в Qt Creator
. Удалить файл `CMakeLists.txt.user` и целевой каталог сборки, например `_build`
. Открыть проект в Qt Creator
====
[QUESTION]
====
[float]
==== Отсутствует необходимый для сборки пакет.
Пример:
image::qtcreator-setup/errors01.png[errors01,align="center"]
====
[ANSWER]
====
. Установить недостающий пакет
. Выполнить menu:Сборка[Запустить CMake]
====

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,54 +0,0 @@
---
title: "Построение профиля местности в QGis"
category: Картография
tags: картография, qgis, sxf, shp, gdal
summary: ""
...
1) В главном меню QGis **Слой****Добавить слой****Добавить векторный слой**
выбрать и открыть файл с векторным слоем, например, `map.sxf`.
2) Среди слоёв выбрать слой с рельефом местности и типом геометрии `LineString`.
![Слои карты](files/qgis-heights1.png)
{: .img-center }
3) На панели **Панель слоёв** правой кнопкой мыши щелкнуть на слое,
содержащем данные о высотах, и выбрать **Фильтр...**.
4) Построить выражение выбирающие только данные с высотами, например,
`"CLNAME" ILIKE '%ГОРИЗОНТАЛИ ОСНОВ%'` и нажить **OK**.
5) На панели **Панель слоёв** правой кнопкой мыши щелкнуть на слое,
содержащем данные о высотах, и выбрать **Сохранить как...**. Появившийся
новый слой **heights** следует удалить.
6) В появившемся диалоговом окне выбрать имя выходного файла, например, `heights`.
![Имя выходного файла](files/qgis-heights2.png)
{: .img-center }
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**.
После этого на карте можно строить профили местности.
![Матрица высот](files/qgis-heights3.png)
{: .img-center }

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,28 +0,0 @@
---
title: "Git: автоматическое сохранение в репозиторий"
category: Программирование
tags: программирование, git
summary: ""
...
Скрипт [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

@ -0,0 +1,37 @@
= Git: замена адреса подмодуля
:title-separator: {sp}|
:category: Программирование
:tags: программирование, git,
Если у подмодулей необходимо заменить адрес синхронизации и/или
имя используемой ветки, то можно отредактировать в корневом
каталоге проекта файл `.gitmodules` и выполнить данный скрипт:
[source,sh]
----
#!/bin/bash
# Замена адресов для подмодулей:
# 1. Отредактировать файл .gitmodules
# 2. Запустить этот скрипт
#
# Параметры:
# - имя подмодуля (если присутствует, то замена
# адреса производится только для данного подмодуля)
M="#"
[ ! -z $1 ] && M="$1"
cat .gitmodules | while read s; do
s=${s/\*/}
s=${s/path = /}
if [ "$M" = "#" -o "x$M" = "x$s" ]; then
rm -rf .git/modules/$s
rm -rf $s
fi
done
git submodule sync
git submodule update
----

View File

@ -1,20 +0,0 @@
---
title: "Git: замена адреса подмодуля"
category: Программирование
tags: программирование, git
summary:
monofontoptions:
- Scale=0.7
...
Если у подмодуля `thirdparty/example` нужно заменить адрес синхронизации
и имя используемой ветки, то в каталоге с файлом `.gitmodules`, в котором
содержится информация об этом подмодуле, нужно выполнить команды:
```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
git submodule update --init --recursive --remote
```

View File

@ -0,0 +1,314 @@
= 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). Отслеживаемые файлы, которые на
<<states,диаграмме>>
обозначены зелёным фоном, могут быть неизменёнными (unmodified),
изменёнными (modified) или подготовленными к фиксации (indexed).
[[states]]
[.text-center]
.Состояния
[plantuml]
----
@startuml
skinparam padding 16
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
----
Основные команды, осуществляющие взаимодействие между рабочим каталогом,
индексом, локальным и удалённым репозиторием, приведены на <<commands,диаграмме>>.
[[commands]]
[.text-center]
.Команды
[plantuml]
----
@startuml
skinparam padding 16
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
----
Пример последовательности действий, выполняемых пользователем в совместном
проекте, приведён на <<workflow,диаграмме>>.
[[workflow]]
[.text-center]
.Последовательность действий
[plantuml]
----
@startuml
skinparam defaultFontSize 24
skinparam padding 16
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 : <font color=red>Начало работы</font>
activate workspace
remote -> local : <font color=red>Получение изменений с сервера</font>\n<b>git fetch</b>
remote -> local : <font color=red>Обновление подмодулей</font>\n<b>git submodule update ~--recursive ~--init</b>
workspace <-> local : <font color=red>Просмотр информации</font>\n<b>git status</b>
workspace <-> local : <font color=red>Переход на ветку master</font>\n<b>git checkout master</b>
local -> workspace : <font color=red>Слияние с удалённой веткой</font>\n<b>git merge origin/master</b>
local <-> workspace : <font color=red>Создание новой ветки</font>\n<b>git branch temp</b>
local <-> workspace : <font color=red>Переход на новую ветку</font>\n<b>git checkout temp</b>
workspace ->o workspace : <font color=red>Редактирование</font>
workspace <-> local : <font color=red>Просмотр изменений</font>\n<b>git diff</b>
workspace -> index : <font color=red>Занесение файлов в индекс</font>\n<b>git add</b>
index -> local : <font color=red>Фиксация изменений</font>\n<b>git commit</b>
local ->o local : <font color=red>Присвоение ветки осмысленного названия</font>\n<b>git branch -m temp new_task</b>
local ->o local : <font color=red>Переход на ветку</font>\n<b>git checkout new_task</b>
remote -> local : <font color=red>Получение изменений с сервера</font>\n<b>git fetch</b>
local ->o local : <font color=red>Слияние изменений с сервера в текущую ветку (new_task)</font>\n<b>git merge origin/master</b>
local -> remote : <font color=red>Отправка ветки на сервер</font>\n<b>git push origin new_task</b>
remote ->] : <font color=red>Создание запроса на слияние</font>
deactivate workspace
@enduml
----
Альтернативный пример действий, выполняемых пользователем в совместном
проекте, приведён на <<workflow-alt,диаграмме>>.
[[workflow-alt]]
[.text-center]
.Альтернативная последовательность действий
[plantuml]
----
@startuml
skinparam defaultFontSize 24
skinparam padding 16
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 : <font color=red>Начало работы</font>
activate workspace
workspace <-> local : <font color=red>Переход на локальную ветку master</font>\n<b>git checkout master</b>
remote -> workspace : <font color=red>Слияние с удалённой веткой и обновление рабочего каталога</font>\n<b>git pull</b>
workspace <-> local : <font color=red>Создание новой ветки</font>\n<b>git checkout -b new_task</b>
workspace ->o workspace : <font color=red>Редактирование</font>
workspace <-> local : <font color=red>Просмотр изменений</font>\n<b>git diff</b>
workspace -> index : <font color=red>Занесение файлов в индекс</font>\n<b>git add</b>
index -> local : <font color=red>Фиксация изменений</font>\n<b>git commit</b>
remote -> local : <font color=red>Получение изменений с сервера</font>\n<b>git fetch</b>
local ->o local : <font color=red>Слияние изменений с сервера в текущую ветку (new_task)</font>\n<b>git merge origin/master</b>
local -> remote : <font color=red>Отправка ветки на сервер</font>\n<b>git push origin new_task</b>
remote ->] : <font color=red>Создание запроса на слияние</font>
deactivate workspace
@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%,20%,65%",options="header",]
|===
| Команда | Ключи | Описание
| `git add` | `<filename>` | Подготовить файл `<filename>` к фиксации
| `git commit` | | Зафиксировать подготовленные файлы
| `git commit` | `-a` | Зафиксировать все отслеживаемые файлы, которые были изменены
|===
== Удаление
[width="100%",cols="15%,20%,65%",options="header",]
|===
| Команда | Ключи | Описание
| `git rm` | `<filename>` | Удалить файл из индекса и рабочего каталога
| `git rm` | `-f <filename>` | Принудительное удаление файла
| `git rm` | `--cached <filename>` | Удаление файла из проекта, но не из рабочего каталога
|===
== Информация
[width="100%",cols="15%,20%,65%",options="header",]
|===
| Команда | Ключи | Описание
| `git status` | `-s` | Вывод информации о рабочем каталоге в краткой форме
| `git log` | `--oneline` | Вывод журнала изменений в краткой форме
| `git ls-files` | | Вывод списка отслеживаемых и подготовленных файлов
|===
== Удалённый репозиторий
[width="100%",cols="15%,20%,65%",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="15%,20%,65%",options="header",]
|===
| Команда | Ключи | Описание
| `git push` | `<remote> <branch>` | Отправить ветку `<branch>` в удалённый репозиторий `<remote>`
| `git push` | `<remote> --all` | Отправить все ветки в удалённый репозиторий `<remote>`
| `git push` | `--d <remote> <branch>` | Удалить ветку `<branch>` из удалённого репозитория `<remote>`
|===
== Получение изменений
[width="100%",cols="15%,20%,65%",options="header",]
|===
| Команда | Ключи | Описание
| `git fetch` | `<remote>` | Получить изменения из всех веток репозитория `<remote>`, но не выполнять слияние
| `git fetch` | `<remote> <branch>` | Получить изменения из ветки `<branch>` репозитория `<remote>`, но не выполнять слияние
| `git merge` | `<remote>/<branch>` | Выполнить слияние с веткой `<branch>` репозитория `<remote>`
| `git pull` | `<remote>` | Получение и слияние
|===
== Ветки
[width="100%",cols="15%,20%,65%",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="15%,20%,65%",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

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

View File

@ -1,27 +1,27 @@
---
title: "Git: репозиторий на переносном устройстве"
category: Программирование
tags: программирование, git
summary:
...
= 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,24 +0,0 @@
---
title: "GitLab — выполнение по расписанию"
category: Программирование
tags: программирование, gitlab, git
summary:
...
После помещения изменений (push) на сервер следует выполнять только задачи,
не требующие много ресурсов. Ресурсоёмкие задачи можно отложить на время
минимальной нагрузки сервера. Для этого нужно:
* в секциях файла `.gitlab-ci.yml`, запускающих задачи с высокой нагрузкой,
добавить
```yaml
only:
- schedules
```
подробнее это описано [здесь](https://docs.gitlab.com/ee/ci/yaml/#only-and-except-simplified)
* в веб-интерфейсе в меню **CI/CD** / **Расписания** добавить **Новое расписание**
и назначить исполнение задачи на время, когда нагрузка на сервер минимальна.

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]

View File

@ -0,0 +1,43 @@
= Qt: обмен бинарными данными с БД
:title-separator: {sp}|
:category: Программирование
:tags: программирование, qt, postgresql, бд
Таблица, с которой осуществляется обмен:
[source,sql]
----
CREATE TABLE example (
id INTEGER,
bin_data BYTEA
);
----
Запись данных:
[source,cpp]
----
const char cart[] = {0x04, 0x43, 0x00, 0x9A};
QByteArray binDataArray(QByteArray::fromRawData(cart, 4));
QSqlQuery query1;
query1.prepare(QString("INSERT INTO example (id, bin_data) VALUES(:id, :bin_data)");
query1.bindValue(":id", 10, QSql::In);
query1.bindValue(":bin_data", binDataArray, QSql::In | QSql::Binary);
query1.exec();
QSqlQuery query2;
query2.exec(QString("INSERT INTO files VALUES(%1, %2);")
.arg(18)
.arg(db.driver()->formatValue(dataField)));
----
Чтение данных:
[source,cpp]
----
QSqlQuery query;
query.exec("SELECT id, bin_data FROM example LIMIT 1");
query.next();
QByteArray binDataArray = query.value(query.record().indexOf("bin_data")).toByteArray();
----

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,28 @@
= Библиотеки для 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{plus}{plus} Core Guidelines]
* http://www.holoborodko.com/pavel/mpfr/[mpfrc{plus}{plus}]: C++ интерфейс
для https://www.mpfr.org/[MPFR]
== Qt
* https://github.com/sjinks/qt_signalwatcher[Обработка сигналов UNIX]

View File

@ -1,28 +0,0 @@
---
title: "Библиотеки для C, C++"
category: Программирование
tags: программирование, C, C++, Qt
summary:
toc: yes
...
[TOC]
### C
* [nanomsg](http://nanomsg.org): сетевое взаимодействие
* [noping](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)
### Qt
* [Обработка сигналов UNIX](https://github.com/sjinks/qt_signalwatcher)

View File

@ -0,0 +1,18 @@
= Сайты и статьи по программированию
:category: Программирование
:tags: программирование, C, C++, Qt,
:toc:
== С++
* https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines[C++ Core Guidelines]
== Qt
* https://woboq.com/blog/how-qt-signals-slots-work.html[How Qt Signals and Slots Work]
== Оптимизация
* https://www.agner.org/optimize[Agner's software optimization resources]
* https://jjj.de[jj's pages (FXT library and Matters Computational)]

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,21 +0,0 @@
---
title: Vimdiff
category: Vim
tags: Vim, команды Vim
summary:
CSS: table-100.css
...
Команды режима `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,24 +0,0 @@
---
title: "Vim: замена выделенного блока"
category: Vim
tags: Vim, команды Vim
summary:
CSS: table-100.css
...
Замену блока, выделенного в режиме 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,27 +0,0 @@
---
title: "Vim: комментирование кода"
category: Vim
tags: Vim, команды Vim
summary:
CSS: table-100.css
...
Отмена автоматического комментирования кода при вставке из буфера:
```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,17 +0,0 @@
---
title: "Vim: навигация по буферам"
category: Vim
tags: Vim, команды Vim
summary:
CSS: table-100.css
...
Команда | Назначение
------------------|-----------------
`: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,22 +0,0 @@
---
title: "Vim: управление окнами"
category: Vim
tags: Vim, команды Vim
summary:
CSS: table-100.css
...
Команда | Назначение
--------------------|-------------------------
`: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>` `стрелки` | перемещение между окнами

View File

@ -1,4 +0,0 @@
table {
width: 100%
}

Some files were not shown because too many files have changed in this diff Show More