aboutsummaryrefslogtreecommitdiff
path: root/documentation/content/ru/books/developers-handbook/tools
diff options
context:
space:
mode:
Diffstat (limited to 'documentation/content/ru/books/developers-handbook/tools')
-rw-r--r--documentation/content/ru/books/developers-handbook/tools/_index.adoc1428
-rw-r--r--documentation/content/ru/books/developers-handbook/tools/_index.po4483
2 files changed, 5911 insertions, 0 deletions
diff --git a/documentation/content/ru/books/developers-handbook/tools/_index.adoc b/documentation/content/ru/books/developers-handbook/tools/_index.adoc
new file mode 100644
index 0000000000..83dbc7784c
--- /dev/null
+++ b/documentation/content/ru/books/developers-handbook/tools/_index.adoc
@@ -0,0 +1,1428 @@
+---
+authors:
+ -
+ author: 'James Raynard'
+ -
+ author: 'Murray Stokely'
+description: 'Инструменты разработки'
+next: books/developers-handbook/secure
+params:
+ path: /books/developers-handbook/tools/
+prev: books/developers-handbook/introduction
+showBookMenu: true
+tags: ["tools", "Interpreters", "Compilers", "cc", "make", "Debugging", "lldb", "gdb", "clang", "Emacs"]
+title: 'Глава 2. Инструменты разработки'
+weight: 3
+---
+
+[[tools]]
+= Инструменты разработки
+:doctype: book
+:toc: macro
+:toclevels: 1
+:icons: font
+:sectnums:
+:sectnumlevels: 6
+:sectnumoffset: 2
+:partnums:
+:source-highlighter: rouge
+:experimental:
+:c-plus-plus-command: c++
+:clang-plus-plus-command: clang++
+:images-path: books/developers-handbook/
+
+ifdef::env-beastie[]
+ifdef::backend-html5[]
+:imagesdir: ../../../../images/{images-path}
+endif::[]
+ifndef::book[]
+include::shared/authors.adoc[]
+include::shared/mirrors.adoc[]
+include::shared/releases.adoc[]
+include::shared/attributes/attributes-{{% lang %}}.adoc[]
+include::shared/{{% lang %}}/teams.adoc[]
+include::shared/{{% lang %}}/mailing-lists.adoc[]
+include::shared/{{% lang %}}/urls.adoc[]
+toc::[]
+endif::[]
+ifdef::backend-pdf,backend-epub3[]
+include::../../../../../shared/asciidoctor.adoc[]
+endif::[]
+endif::[]
+
+ifndef::env-beastie[]
+toc::[]
+include::../../../../../shared/asciidoctor.adoc[]
+endif::[]
+
+[[tools-synopsis]]
+== Обзор
+
+В этой главе представлено введение в использование некоторых инструментов для программирования, поставляемых с FreeBSD, хотя многое из описанного применимо и к другим версиям UNIX(R). Она _не_ претендует на детальное описание процесса написания кода. Большая часть главы предполагает наличие минимальных или отсутствие знаний в программировании, хотя предполагается, что даже опытные программисты найдут в ней что-то полезное.
+
+[[tools-intro]]
+== Введение
+
+FreeBSD предоставляет отличную среду разработки. Компиляторы для C и C++, а также ассемблер входят в базовую систему, не говоря уже о классических инструментах UNIX(R), таких как `sed` и `awk`. Если этого недостаточно, в коллекции Ports доступно множество других компиляторов и интерпретаторов. В следующем разделе, crossref:tools[tools-programming,Введение в программирование], перечислены некоторые из доступных вариантов. FreeBSD обладает высокой совместимостью со стандартами, такими как POSIX(R) и ANSI C, а также с собственным наследием BSD, что позволяет создавать приложения, которые будут компилироваться и запускаться с минимальными изменениями или без них на широком спектре платформ.
+
+Однако вся эта мощь может поначалу ошеломить, если вы никогда раньше не писали программы на платформе UNIX(R). Этот документ призван помочь вам начать работу, не углубляясь слишком сильно в более сложные темы. Цель заключается в том, чтобы дать вам достаточно базовых знаний для понимания документации.
+
+Большая часть документа не требует или почти не требует знаний программирования, хотя предполагает базовые навыки работы с UNIX(R) и готовность учиться!
+
+[[tools-programming]]
+== Введение в программирование
+
+Программа — это набор инструкций, которые указывают компьютеру выполнять различные действия; иногда выполняемая инструкция зависит от результата предыдущей. В этом разделе представлен обзор двух основных способов передачи таких инструкций, или, как их обычно называют, «команд». Один способ использует _интерпретатор_, другой — _компилятор_. Поскольку человеческие языки слишком сложны для однозначного понимания компьютером, команды обычно записываются на одном из специально разработанных для этого языков.
+
+=== Интерпретаторы
+
+С интерпретатором язык поставляется как среда, в которой вы вводите команды в приглашении, и среда выполняет их для вас. Для более сложных программ вы можете ввести команды в файл и заставить интерпретатор загрузить файл и выполнить команды в нём. Если что-то пойдёт не так, многие интерпретаторы переведут вас в отладчик, чтобы помочь найти проблему.
+
+Преимущество этого подхода в том, что вы сразу видите результаты выполнения команд, а ошибки можно легко исправить. Самый большой недостаток проявляется, когда вы хотите поделиться своими программами с кем-то. У них должен быть такой же интерпретатор, или у вас должен быть способ предоставить его, и они должны понимать, как им пользоваться. Кроме того, пользователям может не понравиться, если они попадут в отладчик при нажатии не той клавиши! С точки зрения производительности интерпретаторы могут потреблять много памяти и обычно генерируют код менее эффективно, чем компиляторы.
+
+По моему мнению, интерпретируемые языки — это лучший способ начать, если вы раньше не занимались программированием. Такая среда обычно встречается в языках вроде Lisp, Smalltalk, Perl и Basic. Можно также утверждать, что UNIX(R) shell (`sh`, `csh`) сам по себе является интерпретатором, и многие часто пишут shell-«скрипты» для помощи в различных «хозяйственных» задачах на своих машинах. Действительно, часть оригинальной философии UNIX(R) заключалась в предоставлении множества небольших утилит, которые можно было связывать вместе в shell-скриптах для выполнения полезных задач.
+
+=== Доступные интерпретаторы в FreeBSD
+
+Вот список интерпретаторов, доступных в Коллекции портов FreeBSD, с кратким обзором некоторых наиболее популярных интерпретируемых языков.
+
+Инструкции по получению и установке приложений из Коллекции портов можно найти в extref:{handbook}[разделе Порты, ports-using] руководства.
+
+BASIC::
+Сокращение от Beginner's All-purpose Symbolic Instruction Code. Разработан в 1950-х годах для обучения студентов университетов программированию и поставлялся с каждым уважающим себя персональным компьютером в 1980-х. BASIC — первый язык программирования для многих программистов. Он также является основой для Visual Basic.
++
+Интерпретатор Bywater Basic можно найти в Коллекции портов как package:lang/bwbasic[], а интерпретатор Phil Cockroft's Basic (ранее известный как Rabbit Basic) доступен как package:lang/pbasic[].
+
+Lisp::
+Язык, разработанный в конце 1950-х годов как альтернатива популярным в то время языкам для «численных расчётов». В отличие от них, Lisp основан на списках; фактически, название является сокращением от «List Processing» (обработка списков). Он очень популярен в кругах, связанных с ИИ (искусственным интеллектом).
++
+Lisp — это чрезвычайно мощный и сложный язык, но он может показаться довольно большим и громоздким.
++
+В Коллекции портов FreeBSD доступны различные реализации Lisp, которые могут работать в системах UNIX(R). CLISP от Bruno Haible и Michael Stoll доступен как package:lang/clisp[]. Более простая реализация Lisp, SLisp, доступна как package:lang/slisp[].
+
+Perl::
+Очень популярен среди системных администраторов для написания скриптов; также часто используется на веб-серверах для написания CGI-скриптов.
++
+Perl доступен в Коллекции портов как package:lang/perl5.36[] для всех выпусков FreeBSD.
+
+Scheme::
+Диалект Lisp, который более компактен и чист по сравнению с Common Lisp. Популярен в университетах, так как достаточно прост для обучения студентов в качестве первого языка, и при этом обладает достаточным уровнем абстракции для использования в исследовательской работе.
++
+Схема доступна из Коллекции Портов как package:lang/elk[] для Интерпретатора Elk Scheme. Интерпретатор MIT Scheme можно найти в package:lang/mit-scheme[], а Интерпретатор SCM Scheme — в package:lang/scm[].
+
+Lua::
+Lua — это легковесный встраиваемый язык сценариев. Он обладает высокой переносимостью и относительно прост. Lua доступен в коллекции портов в пакете package:lang/lua54[]. Он также включен в базовую систему как [.filename]#/usr/libexec/flua# для использования компонентами базовой системы. Стороннее программное обеспечение не должно зависеть от [.filename]#flua#.
+
+Python::
+Python — это объектно-ориентированный интерпретируемый язык. Его сторонники утверждают, что это один из лучших языков для начала программирования, поскольку он относительно прост в освоении, но не уступает другим популярным интерпретируемым языкам, используемым для разработки крупных и сложных приложений (Perl и Tcl — два других языка, популярных для таких задач).
++
+Последняя версия Python доступна в Коллекции портов в пакете package:lang/python[].
+
+Ruby::
+Ruby — это интерпретируемый, чисто объектно-ориентированный язык программирования. Он получил широкую популярность благодаря простому для понимания синтаксису, гибкости при написании кода и возможности легко разрабатывать и поддерживать большие, сложные программы.
++
+Ruby доступен в Коллекции портов как package:lang/ruby32[].
+
+Tcl и Tk::
+Tcl — это встраиваемый интерпретируемый язык, который получил широкое распространение и популярность в основном благодаря своей переносимости на множество платформ. Он может использоваться как для быстрого написания небольших прототипов приложений, так и (в сочетании с Tk, набором инструментов для графического интерфейса) полноценных программ с богатым функционалом.
++
+Различные версии Tcl доступны в качестве портов для FreeBSD. Последняя версия, Tcl 8.7, находится в пакете package:lang/tcl87[].
+
+=== Компиляторы
+
+Компиляторы довольно сильно различаются. Прежде всего, вы пишете свой код в файле (или файлах) с помощью редактора. Затем вы запускаете компилятор и проверяете, принимает ли он вашу программу. Если программа не скомпилировалась, стисните зубы и вернитесь к редактору; если же компиляция прошла успешно и программа была создана, вы можете запустить её либо в командной строке оболочки, либо в отладчике, чтобы проверить её работу.footnote:[Если вы запустите её в оболочке, может произойти дамп памяти.]
+
+Очевидно, это требует больше усилий по сравнению с использованием интерпретатора. Однако это позволяет делать множество вещей, которые очень сложны или даже невозможны с интерпретатором, например, писать код, тесно взаимодействующий с операционной системой — или даже создавать собственную операционную систему! Это также полезно, если требуется написать очень эффективный код, так как компилятор может не спешить и оптимизировать код, что было бы неприемлемо в интерпретаторе. Более того, распространение программы, написанной для компилятора, обычно проще, чем для интерпретатора — можно просто предоставить копию исполняемого файла, предполагая, что у пользователя та же операционная система, что и у вас.
+
+Поскольку цикл редактирования-компиляции-запуска-отладки довольно утомителен при использовании отдельных программ, многие производители коммерческих компиляторов создали интегрированные среды разработки (сокращённо IDE). FreeBSD не включает IDE в базовую систему, но в Коллекции портов доступен package:devel/kdevelop[], и многие используют для этой цели Emacs. Использование Emacs в качестве IDE обсуждается в crossref:tools[emacs, Использование Emacs как среды разработки].
+
+[[tools-compiling]]
+== Компиляция с помощью `cc`
+
+Этот раздел посвящён компилятору clang для языков C и C++, так как он устанавливается вместе с базовой системой FreeBSD. Clang устанавливается как `cc`; пакет GNU-компилятора package:lang/gcc[gcc] доступен в Коллекции портов. Детали создания программы с интерпретатором значительно различаются в зависимости от интерпретатора и обычно хорошо описаны в документации и онлайн-справке интерпретатора.
+
+Как только вы напишете свой шедевр, следующий шаг — преобразовать его во что-то, что (надеюсь!) будет работать на FreeBSD. Обычно это включает несколько шагов, каждый из которых выполняется отдельной программой.
+
+[.procedure]
+. Обработь исходный код, чтобы удалить комментарии и выполнить другие действия, такие как раскрытие макросов в C.
+. Проверить синтаксис вашего кода, чтобы убедиться, что вы соблюдаете правила языка. Если нет, он пожалуется!
+. Преобразовать исходный код в ассемблерный язык — это очень близко к машинному коду, но всё ещё понятно человеку. Как утверждается.
+. Преобразовать язык ассемблера в машинный код — да, здесь речь идет о битах и байтах, единицах и нулях.
+. Проверить, что вы использовали такие элементы, как функции и глобальные переменные, правильно и последовательно. Например, если вы вызвали несуществующую функцию, это будет отмечено.
+. Если вы пытаетесь создать исполняемый файл из нескольких исходных файлов, определить, как объединить их все вместе.
+. Определить, как создать что-то, что загрузчик времени выполнения системы сможет загрузить в память и запустить.
+. Наконец, записать исполняемый файл в файловую систему.
+
+Слово _компиляция_ часто относится только к шагам с 1 по 4, а остальные шаги называются _линковкой_. Иногда шаг 1 называют _препроцессированием_, а шаги 3-4 — _ассемблированием_.
+
+К счастью, почти все эти детали скрыты от вас, так как `cc` — это интерфейс, который управляет вызовом всех этих программ с правильными аргументами за вас; достаточно просто набрать
+
+[source, bash]
+....
+% cc foobar.c
+....
+
+и это вызовет компиляцию файла [.filename]#foobar.c# всеми перечисленными выше шагами. Если у вас несколько файлов для компиляции, просто сделайте что-то вроде
+
+[source, bash]
+....
+% cc foo.c bar.c
+....
+
+Обратите внимание, что проверка синтаксиса — это всего лишь проверка синтаксиса. Она не выявит логических ошибок, которые вы могли допустить, например, создание бесконечного цикла или использование пузырьковой сортировки вместо бинарной.footnote:[На случай, если вы не знали: бинарная сортировка — это эффективный способ упорядочивания элементов, в отличие от пузырьковой.]
+
+Существует множество опций для `cc`, все они описаны в руководстве. Вот несколько наиболее важных из них с примерами использования.
+
+`-o _filename_`::
+Имя выходного файла. Если вы не используете эту опцию, `cc` создаст исполняемый файл с именем [.filename]#a.out#.footnote:[Причины этого кроются в глубинах истории.]
++
+[source, bash]
+....
+% cc foobar.c executable is a.out
+% cc -o foobar foobar.c executable is foobar
+....
+
+`-c`::
+Просто скомпилирует файл, не связывая его. Полезно для небольших программ, где нужно только проверить синтаксис, или если вы используете [.filename]#Makefile#.
++
+[source, bash]
+....
+% cc -c foobar.c
+....
++
+Это создаст _объектный файл_ (не исполняемый) с именем [.filename]#foobar.o#. Его можно скомпоновать с другими объектными файлами в исполняемый файл.
+
+`-g`::
+Создать отладочную версию исполняемого файла. Это заставляет компилятор записывать в исполняемый файл информацию о том, какая строка какого исходного файла соответствует какому вызову функции. Отладчик может использовать эту информацию для отображения исходного кода при пошаговом выполнении программы, что _очень_ полезно; недостатком является то, что вся эта дополнительная информация значительно увеличивает размер программы. Обычно вы компилируете с `-g` во время разработки программы, а затем компилируете "релизную версию" без `-g`, когда убедитесь, что она работает правильно.
++
+
+[source, bash]
+....
+% cc -g foobar.c
+....
++
+Это создаст отладочную версию программы. footnote:[Примечание: мы не использовали флаг -o для указания имени исполняемого файла, поэтому получим исполняемый файл с именем a.out. Создание отладочной версии с именем foobar остается упражнением для читателя!]
+
+`-O`::
+Создает оптимизированную версию исполняемого файла. Компилятор применяет различные хитрые приёмы, чтобы попытаться создать исполняемый файл, который работает быстрее обычного. Вы можете добавить число после `-O`, чтобы указать более высокий уровень оптимизации, но это часто выявляет ошибки в оптимизаторе компилятора.
++
+[source, bash]
+....
+% cc -O -o foobar foobar.c
+....
++
+Это создаст оптимизированную версию [.filename]#foobar#.
+
+Следующие три флага заставят `cc` проверять, что ваш код соответствует соответствующему международному стандарту, часто называемому стандартом ANSI, хотя строго говоря, это стандарт ISO.
+
+`-Wall`::
+Включить все предупреждения, которые разработчики `cc` считают полезными. Несмотря на название, это не включит все предупреждения, которые `cc` способен выдавать.
+
+`-ansi`::
+Отключит большинство, но не все, не-ANSI C функции, предоставляемые `cc`. Несмотря на название, это не гарантирует строгого соответствия вашего кода стандарту.
+
+`-pedantic`::
+Отключит _все_ не-ANSI C возможности ``cc``.
+
+Без этих флагов `cc` позволит вам использовать некоторые из своих нестандартных расширений стандарта. Некоторые из них очень полезны, но не будут работать с другими компиляторами — фактически, одна из основных целей стандарта заключается в том, чтобы позволить людям писать код, который будет работать с любым компилятором на любой системе. Это известно как _переносимый код_.
+
+Обычно следует стремиться к тому, чтобы ваш код был как можно более переносимым, иначе позже вам, возможно, придётся полностью переписать программу для её работы в другом месте — а кто знает, что вы будете использовать через несколько лет?
+
+[source, bash]
+....
+% cc -Wall -ansi -pedantic -o foobar foobar.c
+....
+
+В результате будет создан исполняемый файл [.filename]#foobar# после проверки [.filename]#foobar.c# на соответствие стандартам.
+
+`-l__library__`::
+Укажите библиотеку функций, которая будет использоваться во время компоновки.
++
+Наиболее распространённый пример этого — компиляция программы, использующей некоторые математические функции в C. В отличие от большинства других платформ, они находятся в отдельной библиотеке, отличной от стандартной библиотеки C, и необходимо указать компилятору добавить её.
++
+Правило заключается в том, что если библиотека называется [.filename]#libsomething.a#, то вы передаёте `cc` аргумент `-l__something__`. Например, математическая библиотека называется [.filename]#libm.a#, поэтому вы передаёте `cc` аргумент `-lm`. Типичный подводный камень с математической библиотекой заключается в том, что она должна быть последней библиотекой в командной строке.
++
+[source, bash]
+....
+% cc -o foobar foobar.c -lm
+....
++
+Это приведёт к подключению функций математической библиотеки в [.filename]#foobar#.
++
+Если вы компилируете код на C++, используйте {c-plus-plus-command}. {c-plus-plus-command} также может быть вызван как {clang-plus-plus-command} в FreeBSD.
++
+[source, bash]
+....
+% c++ -o foobar foobar.cc
+....
++
+Это создаст исполняемый файл [.filename]#foobar# из исходного файла на C++
+[.filename]#foobar.cc#.
+
+=== Распространённые вопросы и проблемы `cc`
+
+==== Я скомпилировал файл с именем foobar.c и не могу найти исполняемый файл с именем foobar. Куда он пропал?
+
+Помните, что `cc` вызовет исполняемый файл [.filename]#a.out#, если вы не укажете иное. Используйте опцию `-o _имя_файла_`:
+
+[source, bash]
+....
+% cc -o foobar foobar.c
+....
+
+==== Хорошо, у меня есть исполняемый файл с именем foobar, я вижу его при выполнении команды ls, но когда я ввожу foobar в командной строке, система сообщает, что такого файла нет. Почему он не может его найти?
+
+В отличие от MS-DOS(R), UNIX(R) не ищет в текущем каталоге, когда пытается определить, какую программу нужно запустить, если вы явно не укажете это. Введите `./foobar`, что означает "запустить файл с именем [.filename]#foobar# в текущем каталоге."
+
+=== Я назвал свой исполняемый файл test, но при запуске ничего не происходит. В чем дело?
+
+Большинство UNIX(R) систем имеют программу под названием `test` в [.filename]#/usr/bin#, и оболочка выбирает её, прежде чем проверить текущий каталог. Введите следующее:
+
+[source, bash]
+....
+% ./test
+....
+
+или выберите более подходящее название для вашей программы!
+
+==== Я скомпилировал свою программу, и сначала она работала нормально, но потом произошла ошибка, и было сообщение о core dumped. Что это значит?
+
+Название _core dump_ восходит к самым ранним дням UNIX(R), когда машины использовали ферритовую память для хранения данных. По сути, если программа завершалась сбоем при определённых условиях, система записывала содержимое ферритовой памяти на диск в файл с именем [.filename]#core#, который программист затем мог изучить, чтобы выяснить причину ошибки.
+
+==== Увлекательный материал, но что мне теперь делать?
+
+Используйте отладчик для анализа образа памяти (см. crossref:tools[debugging, Отладка]).
+
+==== Когда моя программа сбросила core, она сообщила что-то о segmentation fault. Что это?
+
+Это означает, что ваша программа попыталась выполнить какую-то недопустимую операцию с памятью; UNIX(R) разработана для защиты операционной системы и других программ от некорректно работающих программ.
+
+Распространенные причины этого:
+
+* Попытка записи в NULL-указатель, например:
++
+[.programlisting]
+....
+char *foo = NULL;
+strcpy(foo, "bang!");
+....
+
+* Использование неинициализированного указателя, например:
++
+[.programlisting]
+....
+char *foo;
+strcpy(foo, "bang!");
+....
++
+Указатель будет иметь случайное значение, которое, возможно, укажет на область памяти, недоступную вашей программе, и ядро завершит вашу программу до того, как она сможет нанести какой-либо ущерб. Если вам не повезет, он укажет внутрь вашей собственной программы и повредит одну из структур данных, что приведет к загадочному сбою программы.
+* Попытка доступа за пределы массива, например
++
+[.programlisting]
+....
+int bar[20];
+bar[27] = 6;
+....
+
+* Попытка сохранить что-то в память только для чтения, например
++
+[.programlisting]
+....
+char *foo = "My string";
+strcpy(foo, "bang!");
+....
++
+Версии UNIX(R) компиляторы часто помещают строковые литералы, такие как `"Моя строка"`, в области памяти только для чтения.
+* Выполнение нежелательных действий с `malloc()` и `free()`, например
++
+[.programlisting]
+....
+char bar[80];
+free(bar);
+....
++
+или
++
+[.programlisting]
+....
+char *foo = malloc(27);
+free(foo);
+free(foo);
+....
+
+Совершение одной из этих ошибок не всегда приведет к сбою, но это всегда плохая практика. Некоторые системы и компиляторы более терпимы, чем другие, поэтому программы, которые хорошо работают на одной системе, могут аварийно завершаться при попытке запустить их на другой.
+
+==== Иногда при получении дампа памяти я вижу сообщение ошибки шины (bus error). В моей книге по UNIX(R) сказано, что это означает аппаратную проблему, но компьютер продолжает работать. Это правда?
+
+Нет, к счастью, нет (если, конечно, у вас действительно нет аппаратной проблемы...). Обычно это означает, что вы обратились к памяти способом, который не следует использовать.
+
+==== Этот процесс создания дампа памяти звучит довольно полезно, если я могу запускать его по своему желанию. Могу ли я это сделать, или нужно ждать возникновения ошибки?
+
+Можете. Просто перейдите на другую консоль или xterm, выполните
+
+[source, bash]
+....
+% ps
+....
+
+чтобы узнать идентификатор процесса вашей программы и выполните
+
+[source, bash]
+....
+% kill -ABRT pid
+....
+
+где `_pid_` — идентификатор процесса, который вы нашли.
+
+Это полезно, если ваша программа зависла в бесконечном цикле, например. Если ваша программа перехватывает SIGABRT, есть несколько других сигналов, которые оказывают аналогичный эффект.
+
+В качестве альтернативы, вы можете создать дамп памяти изнутри вашей программы, вызвав функцию `abort()`. Дополнительную информацию можно найти на man:abort[3].
+
+Если вы хотите создать дамп памяти извне вашей программы, но не хотите завершать процесс, вы можете использовать программу `gcore`. Подробнее см. на странице руководства man:gcore[1].
+
+[[tools-make]]
+== Make
+
+=== Что такое `make`?
+
+Когда вы работаете над простой программой с одним или двумя исходными файлами, вводя
+
+[source, bash]
+....
+% cc file1.c file2.c
+....
+
+это не слишком плохо, но быстро становится очень утомительным, когда есть несколько файлов — и компиляция тоже может занять время.
+
+Один из способов обойти это — использовать объектные файлы и перекомпилировать исходный файл только в случае изменения исходного кода. Таким образом, у нас может получиться что-то вроде:
+
+[source, bash]
+....
+% cc file1.o file2.o … file37.c …
+....
+
+если бы мы изменили файл [.filename]#file37.c#, но не трогали остальные с момента последней компиляции. Это может значительно ускорить компиляцию, но не решает проблему с вводом.
+
+Или мы могли бы написать shell-скрипт для решения проблемы с вводом, но тогда пришлось бы перекомпилировать всё, что сделало бы его очень неэффективным для крупного проекта.
+
+Что произойдет, если у нас есть сотни исходных файлов? Что, если мы работаем в команде с другими людьми, которые забывают сообщить нам, когда они изменили один из своих исходных файлов, которые мы используем?
+
+Возможно, мы могли бы объединить два решения и написать что-то вроде shell-скрипта, который содержал бы какое-то волшебное правило, указывающее, когда исходный файл нужно компилировать. Теперь нам осталось только найти программу, которая сможет понимать эти правила, так как для shell это немного слишком сложно.
+
+Эта программа называется `make`. Она читает файл, называемый _makefile_, который указывает, как различные файлы зависят друг от друга, и определяет, какие файлы нужно перекомпилировать, а какие нет. Например, правило может звучать так: «если [.filename]#fromboz.o# старше, чем [.filename]#fromboz.c#, значит, кто-то изменил [.filename]#fromboz.c#, и его нужно перекомпилировать». В makefile также содержатся правила, указывающие make, _как_ именно перекомпилировать исходный файл, что делает эту программу гораздо более мощным инструментом.
+
+Файлы Makefile обычно хранятся в том же каталоге, что и исходный код, к которому они применяются, и могут называться [.filename]#makefile#, [.filename]#Makefile# или [.filename]#MAKEFILE#. Большинство программистов используют имя [.filename]#Makefile#, так как это помещает его в начало списка файлов в каталоге, где его легко заметить.footnote:[Они не используют форму MAKEFILE, так как заглавные буквы часто применяются для файлов документации, таких как README.]
+
+=== Пример использования `make`
+
+Вот очень простой файл для make:
+
+[.programlisting]
+....
+foo: foo.c
+ cc -o foo foo.c
+....
+
+Он состоит из двух строк: строки зависимости и строки создания.
+
+Строка зависимости здесь состоит из имени программы (известного как _цель_), за которым следует двоеточие, пробел и имя исходного файла. Когда `make` читает эту строку, он проверяет, существует ли файл [.filename]#foo#; если он существует, программа сравнивает время последнего изменения файла [.filename]#foo# с временем последнего изменения файла [.filename]#foo.c#. Если файл [.filename]#foo# не существует или старше файла [.filename]#foo.c#, программа смотрит на строку создания, чтобы выяснить, что делать. Другими словами, это правило для определения, когда файл [.filename]#foo.c# нужно перекомпилировать.
+
+Строка создания начинается с табуляции (нажмите kbd:[tab]), а затем следует команда, которую вы бы ввели для создания [.filename]#foo#, если бы делали это в командной строке. Если [.filename]#foo# устарел или не существует, `make` выполняет эту команду для его создания. Другими словами, это правило, которое сообщает make, как перекомпилировать [.filename]#foo.c#.
+
+Таким образом, при вводе команды `make` система обеспечит актуальность файла [.filename]#foo# относительно последних изменений в [.filename]#foo.c#. Этот принцип можно распространить на [.filename]#Makefile#, содержащие сотни целей — фактически, в FreeBSD можно собрать всю операционную систему, просто введя `make buildworld buildkernel` в корневом каталоге дерева исходных кодов (src).
+
+Еще одно полезное свойство makefile заключается в том, что цели не обязательно должны быть программами. Например, у нас может быть makefile, который выглядит так:
+
+[.programlisting]
+....
+foo: foo.c
+ cc -o foo foo.c
+
+install:
+ cp foo /home/me
+....
+
+Мы можем указать make, какую цель мы хотим собрать, набрав:
+
+[source, bash]
+....
+% make target
+....
+
+`make` будет рассматривать только указанную цель и игнорировать все остальные. Например, если мы введём `make foo` с указанным выше makefile, make проигнорирует цель `install`.
+
+Если мы просто введем `make` без параметров, make всегда будет обращаться к первой цели и затем остановится, не рассматривая остальные. Поэтому если мы введем `make` здесь, он просто перейдет к цели `foo`, перекомпилирует [.filename]#foo# при необходимости и затем остановится, не переходя к цели `install`.
+
+Обратите внимание, что цель `install` не зависит ни от чего! Это означает, что команда в следующей строке всегда выполняется при попытке создать эту цель с помощью команды `make install`. В данном случае она скопирует [.filename]#foo# в домашний каталог пользователя. Это часто используется в makefile приложений, чтобы приложение можно было установить в правильный каталог после успешной компиляции.
+
+Это немного запутанная тема для объяснения. Если вы не до конца понимаете, как работает `make`, лучше всего написать простую программу, например, "hello world", и make-файл, как указано выше, и поэкспериментировать. Затем можно перейти к использованию нескольких исходных файлов или добавлению заголовочного файла в исходный код. В этом случае очень полезен `touch` — он изменяет дату файла без необходимости его редактирования.
+
+=== make и include-файлы
+
+Код на C часто начинается со списка подключаемых файлов, например stdio.h. Некоторые из этих файлов являются системными, а некоторые принадлежат текущему проекту:
+
+[.programlisting]
+....
+#include <stdio.h>
+#include "foo.h"
+
+int main(....
+....
+
+Чтобы убедиться, что этот файл перекомпилируется при изменении [.filename]#foo.h#, необходимо добавить его в [.filename]#Makefile#:
+
+[.programlisting]
+....
+foo: foo.c foo.h
+....
+
+В момент, когда ваш проект становится больше и у вас появляется все больше собственных включаемых файлов для поддержки, отслеживание всех включаемых файлов и файлов, которые от них зависят, становится проблемой. Если вы измените включаемый файл, но забудете перекомпилировать все файлы, которые от него зависят, последствия будут катастрофическими. У `clang` есть опция для анализа ваших файлов и создания списка включаемых файлов и их зависимостей: `-MM`.
+
+Если вы добавите это в ваш Makefile:
+
+[.programlisting]
+....
+depend:
+ cc -E -MM *.c > .depend
+....
+
+и выполните `make depend`, появится файл [.filename]#.depend# со списком объектных файлов, C-файлов и включаемых файлов:
+
+[.programlisting]
+....
+foo.o: foo.c foo.h
+....
+
+Если вы измените файл [.filename]#foo.h#, при следующем запуске `make` все файлы, зависящие от [.filename]#foo.h#, будут перекомпилированы.
+
+Не забудьте выполнить `make depend` каждый раз, когда вы добавляете include-файл в один из своих файлов.
+
+=== Файлы Makefile системы FreeBSD
+
+Makefile-ы могут быть довольно сложными для написания. К счастью, в BSD-системах, таких как FreeBSD, есть очень мощные Makefile-ы, поставляемые в составе системы. Отличным примером этого является система портов FreeBSD. Вот основная часть типичного [.filename]#Makefile# для портов:
+
+[.programlisting]
+....
+MASTER_SITES= ftp://freefall.cdrom.com/pub/FreeBSD/LOCAL_PORTS/
+DISTFILES= scheme-microcode+dist-7.3-freebsd.tgz
+
+.include <bsd.port.mk>
+....
+
+Теперь, если мы перейдем в каталог этого порта и наберем `make`, произойдет следующее:
+
+[.procedure]
+. Проверяется, есть ли исходный код этого порта уже в системе.
+. Если это не так, устанавливается FTP-соединение с URL в MASTER_SITES для загрузки исходного кода.
+. Контрольная сумма исходного кода вычисляется и сравнивается с контрольной суммой известной и хорошей копии исходного кода. Это делается для того, чтобы убедиться, что исходный код не был поврежден во время передачи.
+. Все необходимые изменения для адаптации исходного кода к работе в FreeBSD применяются — это называется применением _патча_.
+. Любая необходимая специальная настройка для исходного кода выполнена. (Многие дистрибутивы программ UNIX(R) пытаются определить, на какой версии UNIX(R) они компилируются и какие дополнительные функции UNIX(R) доступны — именно здесь они получают эту информацию в сценарии портов FreeBSD).
+. Компилируется исходный код программы. По сути, мы переходим в каталог, куда были распакованы исходные файлы, и выполняем `make` — собственный make-файл программы содержит необходимую информацию для сборки программы.
+. Теперь у нас есть скомпилированная версия программы. При желании мы можем протестировать её сейчас; когда мы уверены в программе, можно ввести `make install`. Это приведёт к копированию программы и всех необходимых вспомогательных файлов в нужные места, а также к добавлению записи в `базу данных пакетов`, чтобы позже можно было легко удалить порт, если мы передумаем.
+
+Вот теперь, я думаю, вы согласитесь, что это довольно впечатляюще для скрипта из четырёх строк!
+
+Секрет кроется в последней строке, которая указывает `make` обратиться к системному makefile под названием [.filename]#bsd.port.mk#. Эту строку легко пропустить, но именно здесь начинается вся магия — кто-то написал makefile, который предписывает `make` выполнить все вышеперечисленные действия (плюс несколько других, которые я не упомянул, включая обработку возможных ошибок), и любой может получить доступ к этому функционалу, просто добавив одну строку в свой собственный makefile!
+
+Если вы хотите взглянуть на эти системные makefile-ы, они находятся в [.filename]#/usr/share/mk#, но, вероятно, лучше подождать, пока у вас не появится немного практики с makefile, так как они очень сложные (и если вы всё же решите их посмотреть, убедитесь, что у вас под рукой есть фляга крепкого кофе!)
+
+=== Более сложные способы использования `make`
+
+`Make` — это очень мощный инструмент, способный на гораздо большее, чем показано в простом примере выше. К сожалению, существует несколько различных версий `make`, и все они значительно отличаются друг от друга. Лучший способ узнать, на что они способны, — вероятно, прочитать документацию. Надеюсь, это введение дало вам основу, с которой вы сможете это сделать. В man:make[1] подробно обсуждаются переменные, аргументы и то, как использовать `make`.
+
+Многие приложения в портах используют GNU make, который имеет очень хороший набор страниц "info". Если вы установили любой из этих портов, GNU make будет автоматически установлен как `gmake`. Он также доступен как отдельный порт и пакет.
+
+Для просмотра справочных страниц (info) GNU make вам потребуется отредактировать файл [.filename]#dir# в каталоге [.filename]#/usr/local/info#, добавив соответствующую запись. Добавьте строку
+
+[.programlisting]
+....
+ * Make: (make). The GNU Make utility.
+....
+
+в файл. После этого вы можете ввести `info` и затем выбрать [.guimenuitem]#make# из меню (или в Emacs выполнить `C-h i`).
+
+[[debugging]]
+== Отладка
+
+=== Обзор отладчиков, поставляемых в системе
+
+Использование отладчика позволяет запускать программу в более контролируемых условиях. Обычно можно выполнять программу построчно, проверять значения переменных, изменять их, указывать отладчику выполнение до определённой точки и затем останавливаться и так далее. Также можно подключиться к уже работающей программе или загрузить core-файл, чтобы исследовать причину аварийного завершения программы.
+
+Этот раздел представляет собой краткое введение в использование отладчиков и не затрагивает специализированные темы, такие как отладка ядра. Для получения дополнительной информации по этой теме обратитесь к главе crossref:kerneldebug[kerneldebug,Отладка ядра].
+
+Стандартный отладчик, поставляемый с FreeBSD, называется `lldb` (LLVM debugger). Поскольку он является частью стандартной установки для данного выпуска, нет необходимости выполнять какие-либо дополнительные действия для его использования. Он обладает хорошей справкой по командам, доступной через команду `help`, а также https://lldb.llvm.org/[руководством и документацией в интернете].
+
+[NOTE]
+====
+Команда `lldb` также доступна extref:{handbook}ports/[из портов или пакетов, ports-using] как пакет package:devel/llvm[].
+====
+
+Другой отладчик, доступный в FreeBSD, называется `gdb` (GNU debugger). В отличие от lldb, он не устанавливается по умолчанию в FreeBSD; для его использования необходимо extref:{handbook}#ports-using/[установить] пакет package:devel/gdb[] из портов или пакетов. Он обладает отличной встроенной справкой, а также набором info-страниц.
+
+Два отладчика обладают схожим набором функций, поэтому выбор между ними в основном зависит от личных предпочтений. Если вы знакомы только с одним из них, используйте его. Тем, кто не знаком ни с одним или знаком с обоими, но хочет использовать отладчик внутри Emacs, придётся выбрать `gdb`, так как `lldb` не поддерживается Emacs. В остальных случаях попробуйте оба и решите, какой вам больше нравится.
+
+=== Использование lldb
+
+==== Запуск lldb
+
+Запустите lldb, набрав
+
+[source, bash]
+....
+% lldb -- progname
+....
+
+==== Запуск программы с lldb
+
+Скомпилируйте программу с `-g`, чтобы максимально использовать возможности `lldb`. Без этого флаг она будет работать, но отображать только имя текущей выполняемой функции вместо исходного кода. Если отображается строка вида:
+
+[source, bash]
+....
+Breakpoint 1: where = temp`main, address = …
+....
+
+(без указания имени файла исходного кода и номера строки) при установке точки останова это означает, что программа не была скомпилирована с параметром `-g`.
+
+[TIP]
+====
+Большинство команд `lldb` имеют более короткие формы, которые можно использовать вместо полных. Здесь используются полные формы для ясности.
+====
+
+На строке `lldb` введите `breakpoint set -n main`. Это укажет отладчику не показывать предварительный код настройки в запускаемой программе и остановить выполнение в начале кода программы. Теперь введите `process launch`, чтобы фактически запустить программу — она начнётся с кода настройки, а затем будет остановлена отладчиком при вызове `main()`.
+
+Для пошагового выполнения программы строка за строкой введите `thread step-over`. Когда программа дойдёт до вызова функции, войдите в неё, набрав `thread step-in`. Оказавшись внутри вызова функции, вернитесь из него с помощью команды `thread step-out` или используйте `up` и `down`, чтобы быстро посмотреть на вызывающий код.
+
+Вот простой пример того, как найти ошибку в программе с помощью `lldb`. Это наша программа (с умышленной ошибкой):
+
+[.programlisting]
+....
+#include <stdio.h>
+
+int bazz(int anint);
+
+main() {
+ int i;
+
+ printf("This is my program\n");
+ bazz(i);
+ return 0;
+}
+
+int bazz(int anint) {
+ printf("You gave me %d\n", anint);
+ return anint;
+}
+....
+
+Эта программа устанавливает значение `i` равным `5` и передает его в функцию `bazz()`, которая выводит переданное число.
+
+Компиляция и запуск программы отображают
+
+[source, bash]
+....
+% cc -g -o temp temp.c
+% ./temp
+This is my program
+anint = -5360
+....
+
+Это не то, что ожидалось! Пора разобраться, что происходит!
+
+[source, bash]
+....
+% lldb -- temp
+(lldb) target create "temp"
+Current executable set to 'temp' (x86_64).
+(lldb) breakpoint set -n main Skip the set-up code
+Breakpoint 1: where = temp`main + 15 at temp.c:8:2, address = 0x00000000002012ef lldb puts breakpoint at main()
+(lldb) process launch Run as far as main()
+Process 9992 launching
+Process 9992 launched: '/home/pauamma/tmp/temp' (x86_64) Program starts running
+
+Process 9992 stopped
+* thread #1, name = 'temp', stop reason = breakpoint 1.1 lldb stops at main()
+ frame #0: 0x00000000002012ef temp`main at temp.c:8:2
+ 5 main() {
+ 6 int i;
+ 7
+-> 8 printf("This is my program\n"); Indicates the line where it stopped
+ 9 bazz(i);
+ 10 return 0;
+ 11 }
+(lldb) thread step-over Go to next line
+This is my program Program prints out
+Process 9992 stopped
+* thread #1, name = 'temp', stop reason = step over
+ frame #0: 0x0000000000201300 temp`main at temp.c:9:7
+ 6 int i;
+ 7
+ 8 printf("This is my program\n");
+-> 9 bazz(i);
+ 10 return 0;
+ 11 }
+ 12
+(lldb) thread step-in step into bazz()
+Process 9992 stopped
+* thread #1, name = 'temp', stop reason = step in
+ frame #0: 0x000000000020132b temp`bazz(anint=-5360) at temp.c:14:29 lldb displays stack frame
+ 11 }
+ 12
+ 13 int bazz(int anint) {
+-> 14 printf("You gave me %d\n", anint);
+ 15 return anint;
+ 16 }
+(lldb)
+....
+
+Подождите минуту! Как переменная `int` стала равна `-5360`? Разве она не была установлена в `5` в `main()`? Давайте поднимемся к `main()` и посмотрим.
+
+[source, bash]
+....
+(lldb) up Move up call stack
+frame #1: 0x000000000020130b temp`main at temp.c:9:2 lldb displays stack frame
+ 6 int i;
+ 7
+ 8 printf("This is my program\n");
+-> 9 bazz(i);
+ 10 return 0;
+ 11 }
+ 12
+(lldb) frame variable i Show us the value of i
+(int) i = -5360 lldb displays -5360
+....
+
+О боже! Глядя на код, мы забыли инициализировать i. Мы хотели добавить
+
+[.programlisting]
+....
+...
+main() {
+ int i;
+
+ i = 5;
+ printf("This is my program\n");
+...
+....
+
+но мы пропустили строку `i=5;`. Поскольку мы не инициализировали `i`, она содержала любое число, которое оказалось в той области памяти при запуске программы, и в данном случае это оказалось `-5360`.
+
+[NOTE]
+====
+Команда `lldb` отображает стек вызовов каждый раз, когда мы входим в функцию или выходим из неё, даже если мы используем `up` и `down` для перемещения по стеку вызовов. Это показывает имя функции и значения её аргументов, что помогает отслеживать текущее положение и происходящее. (Стек — это область хранения, где программа сохраняет информацию об аргументах, переданных в функции, и о том, куда возвращаться после вызова функции.)
+====
+
+==== Изучение файла Core с помощью lldb
+
+Файл core — это, по сути, файл, содержащий полное состояние процесса на момент его аварийного завершения. В «старые добрые времена» программистам приходилось распечатывать шестнадцатеричные дампы файлов core и корпеть над руководствами по машинному коду, но сейчас жизнь стала немного проще. Кстати, в FreeBSD и других системах на базе 4.4BSD файл core называется [.filename]#progname.core#, а не просто [.filename]#core#, чтобы было понятнее, какой программе он принадлежит.
+
+Для анализа файла core укажите имя файла core в дополнение к самой программе. Вместо обычного запуска `lldb` введите `lldb -c _имя_программы_.core \-- _имя_программы_`.
+
+Отладчик отобразит что-то вроде этого:
+
+[source, bash, subs="verbatim,quotes"]
+....
+% lldb -c [.filename]#progname.core# -- [.filename]#progname#
+(lldb) target create "[.filename]#progname#" --core "[.filename]#progname#.core"
+Core file '/home/pauamma/tmp/[.filename]#progname.core#' (x86_64) was loaded.
+(lldb)
+....
+
+В этом случае программа называлась [.filename]#progname#, поэтому файл дампа имеет имя [.filename]#progname.core#. Отладчик не показывает, почему программа завершилась аварийно или где это произошло. Для этого используйте команду `thread backtrace all`. Она также покажет, как была вызвана функция, в которой программа завершилась дампом ядра.
+
+[source, bash, subs="verbatim,quotes"]
+....
+(lldb) thread backtrace all
+* thread #1, name = 'progname', stop reason = signal SIGSEGV
+ * frame #0: 0x0000000000201347 progname`bazz(anint=5) at temp2.c:17:10
+ frame #1: 0x0000000000201312 progname`main at temp2.c:10:2
+ frame #2: 0x000000000020110f progname`_start(ap=<unavailable>, cleanup=<unavailable>) at crt1.c:76:7
+(lldb)
+....
+
+`SIGSEGV` указывает, что программа пыталась получить доступ к памяти (обычно выполнить код или прочитать/записать данные) по адресу, который ей не принадлежит, но не предоставляет конкретных деталей. Для этого обратитесь к исходному коду на строке 10 файла temp2.c, в функции `bazz()`. Трассировка также показывает, что в данном случае `bazz()` была вызвана из `main()`.
+
+==== Подключение к работающей программе с помощью lldb
+
+Одной из самых замечательных особенностей `lldb` является возможность подключения к уже работающей программе. Конечно, для этого требуются соответствующие разрешения. Распространённая проблема — пошаговое выполнение программы, которая создаёт ответвления, с необходимостью отслеживать дочерний процесс, но отладчик отслеживает только родительский.
+
+Для этого запустите другой `lldb`, используйте `ps` для поиска идентификатора процесса дочернего процесса и выполните
+
+[source, bash]
+....
+(lldb) process attach -p pid
+....
+
+в `lldb`, а затем отлаживайте как обычно.
+
+Для того чтобы это работало правильно, код, который вызывает `fork` для создания дочернего процесса, должен делать что-то вроде следующего (предоставлено из документации `gdb`):
+
+[.programlisting]
+....
+...
+if ((pid = fork()) < 0) /* _Always_ check this */
+ error();
+else if (pid == 0) { /* child */
+ int PauseMode = 1;
+
+ while (PauseMode)
+ sleep(10); /* Wait until someone attaches to us */
+ ...
+} else { /* parent */
+ ...
+....
+
+Вот все, что нужно сделать: подключиться к дочернему процессу, установить `PauseMode` в `0` с помощью `expr PauseMode = 0` и дождаться возврата из вызова `sleep()`.
+
+=== Удаленная отладка с использованием LLDB
+
+[NOTE]
+====
+Описанная функциональность доступна начиная с версии LLDB 12.0.0. Пользователи релизов FreeBSD, содержащих более раннюю версию LLDB, могут воспользоваться снимком из extref:{handbook}[портов или пакетов, ports-using], как package:devel/llvm-devel[].
+====
+
+Начиная с LLDB 12.0.0, удалённая отладка поддерживается в FreeBSD. Это означает, что `lldb-server` может быть запущен для отладки программы на одном узле, в то время как интерактивный клиент `lldb` подключается к нему с другого.
+
+Чтобы запустить новый процесс для удалённой отладки, выполните `lldb-server` на удалённом сервере, набрав
+
+[source, bash]
+....
+% lldb-server g host:port -- progname
+....
+
+Процесс будет остановлен сразу после запуска, и `lldb-server` будет ожидать подключения клиента.
+
+Запустите `lldb` локально и введите следующую команду для подключения к удалённому серверу:
+
+[source, bash]
+....
+(lldb) gdb-remote host:port
+....
+
+`lldb-server` также может присоединиться к работающему процессу. Для этого введите следующее на удалённом сервере:
+
+[source, bash]
+....
+% lldb-server g host:port --attach pid-or-name
+....
+
+=== Использование gdb
+
+==== Запуск gdb
+
+Запустите gdb, набрав
+
+[source, bash]
+....
+% gdb progname
+....
+
+хотя многие предпочитают запускать его внутри Emacs. Для этого введите:
+
+[source, bash]
+....
+ M-x gdb RET progname RET
+....
+
+Наконец, для тех, кого отпугивает текстовый интерфейс командной строки, существует графический интерфейс (package:devel/xxgdb[]) в Коллекции портов.
+
+==== Запуск программы под отладчиком gdb
+
+Скомпилируйте программу с `-g`, чтобы максимально использовать возможности `gdb`. Она будет работать и без этого, но отобразит только имя текущей выполняемой функции вместо исходного кода. Строка вида:
+
+[source, bash]
+....
+... (no debugging symbols found) ...
+....
+
+когда `gdb` запускается, это означает, что программа не была скомпилирована с опцией `-g`.
+
+На приглашении `gdb` введите `break main`. Это укажет отладчику пропустить предварительный код настройки в выполняемой программе и остановить выполнение в начале кода программы. Теперь введите `run`, чтобы запустить программу — она начнётся с начала кода настройки, а затем будет остановлена отладчиком при вызове `main()`.
+
+Для пошагового выполнения программы нажимайте `n`. При вызове функции войдите в неё, нажав `s`. Оказавшись внутри функции, вернитесь из неё, нажав `f`, или используйте `up` и `down` для быстрого просмотра вызывающего кода.
+
+Вот простой пример того, как найти ошибку в программе с помощью `gdb`. Это наша программа (с умышленной ошибкой):
+
+[.programlisting]
+....
+#include <stdio.h>
+
+int bazz(int anint);
+
+main() {
+ int i;
+
+ printf("This is my program\n");
+ bazz(i);
+ return 0;
+}
+
+int bazz(int anint) {
+ printf("You gave me %d\n", anint);
+ return anint;
+}
+....
+
+Эта программа устанавливает значение `i` равным `5` и передает его в функцию `bazz()`, которая выводит переданное число.
+
+Компиляция и запуск программы отображают
+
+[source, bash]
+....
+% cc -g -o temp temp.c
+% ./temp
+This is my program
+anint = 4231
+....
+
+Это было не то, что мы ожидали! Пора разобраться, что происходит!
+
+[source, bash]
+....
+% gdb temp
+GDB is free software and you are welcome to distribute copies of it
+ under certain conditions; type "show copying" to see the conditions.
+There is absolutely no warranty for GDB; type "show warranty" for details.
+GDB 4.13 (i386-unknown-freebsd), Copyright 1994 Free Software Foundation, Inc.
+(gdb) break main Skip the set-up code
+Breakpoint 1 at 0x160f: file temp.c, line 9. gdb puts breakpoint at main()
+(gdb) run Run as far as main()
+Starting program: /home/james/tmp/temp Program starts running
+
+Breakpoint 1, main () at temp.c:9 gdb stops at main()
+(gdb) n Go to next line
+This is my program Program prints out
+(gdb) s step into bazz()
+bazz (anint=4231) at temp.c:17 gdb displays stack frame
+(gdb)
+....
+
+Подождите минуту! Как `int` стал равен `4231`? Разве он не был установлен в `5` в `main()`? Давайте поднимемся к `main()` и посмотрим.
+
+[source, bash]
+....
+(gdb) up Move up call stack
+#1 0x1625 in main () at temp.c:11 gdb displays stack frame
+(gdb) p i Show us the value of i
+$1 = 4231 gdb displays 4231
+....
+
+О боже! Глядя на код, мы забыли инициализировать i. Мы хотели добавить
+
+[.programlisting]
+....
+...
+main() {
+ int i;
+
+ i = 5;
+ printf("This is my program\n");
+...
+....
+
+но мы пропустили строку `i=5;`. Поскольку мы не инициализировали `i`, она содержала любое число, которое оказалось в той области памяти при запуске программы, и в данном случае это оказалось `4231`.
+
+[NOTE]
+====
+Команда `gdb` отображает стек вызовов каждый раз при входе в функцию или выходе из неё, даже при использовании `up` и `down` для перемещения по стеку вызовов. Это показывает имя функции и значения её аргументов, что помогает отслеживать текущее положение и происходящее. (Стек — это область хранения, где программа сохраняет информацию об аргументах, переданных в функции, и о месте, куда нужно вернуться после вызова функции.)
+====
+
+==== Изучение файла core с помощью gdb
+
+Файл core — это, по сути, файл, содержащий полное состояние процесса на момент его аварийного завершения. В «старые добрые времена» программистам приходилось распечатывать шестнадцатеричные дампы файлов core и корпеть над руководствами по машинному коду, но сейчас жизнь стала немного проще. Кстати, в FreeBSD и других системах на базе 4.4BSD файл core называется [.filename]#progname.core#, а не просто [.filename]#core#, чтобы было понятнее, какой программе он принадлежит.
+
+Для анализа файла core запустите `gdb` обычным способом. Вместо ввода команд `break` или `run` введите
+
+[source, bash]
+....
+(gdb) core progname.core
+....
+
+Если файл core отсутствует в текущем каталоге, сначала введите `dir /путь/к/core/файлу`.
+
+Отладчик должен отобразить что-то вроде этого:
+
+[source, bash, subs="verbatim,quotes"]
+....
+% gdb [.filename]#progname#
+GDB is free software and you are welcome to distribute copies of it
+ under certain conditions; type "show copying" to see the conditions.
+There is absolutely no warranty for GDB; type "show warranty" for details.
+GDB 4.13 (i386-unknown-freebsd), Copyright 1994 Free Software Foundation, Inc.
+(gdb) core [.filename]#progname.core#
+Core was generated by `[.filename]#progname#'.
+Program terminated with signal 11, Segmentation fault.
+Cannot access memory at address 0x7020796d.
+#0 0x164a in bazz (anint=0x5) at temp.c:17
+(gdb)
+....
+
+В этом случае программа называлась [.filename]#progname#, поэтому файл дампа памяти называется [.filename]#progname.core#. Мы видим, что программа завершилась аварийно из-за попытки доступа к области памяти, которая ей не доступна, в функции `bazz`.
+
+Иногда полезно увидеть, как была вызвана функция, поскольку проблема могла возникнуть гораздо выше по стеку вызовов в сложной программе. `bt` заставляет `gdb` вывести трассировку стека вызовов:
+
+[source, bash]
+....
+(gdb) bt
+#0 0x164a in bazz (anint=0x5) at temp.c:17
+#1 0xefbfd888 in end ()
+#2 0x162c in main () at temp.c:11
+(gdb)
+....
+
+Функция `end()` вызывается при аварийном завершении программы; в данном случае функция `bazz()` была вызвана из `main()`.
+
+==== Подключение к работающей программе с помощью gdb
+
+Одной из самых удобных функций `gdb` является возможность подключения к уже запущенной программе. Конечно, для этого требуются соответствующие разрешения. Частой проблемой является пошаговое выполнение программы, которая создает дочерний процесс, когда нужно отслеживать дочерний процесс, но отладчик продолжает отслеживать только родительский.
+
+Для этого запустите другой `gdb`, используйте `ps` для поиска идентификатора процесса дочернего элемента и выполните
+
+[source, bash]
+....
+(gdb) attach pid
+....
+
+в `gdb`, а затем отлаживайте как обычно.
+
+Для того чтобы это работало правильно, код, который вызывает `fork` для создания дочернего процесса, должен делать что-то вроде следующего (предоставлено из документации `gdb`):
+
+[.programlisting]
+....
+...
+if ((pid = fork()) < 0) /* _Always_ check this */
+ error();
+else if (pid == 0) { /* child */
+ int PauseMode = 1;
+
+ while (PauseMode)
+ sleep(10); /* Wait until someone attaches to us */
+ ...
+} else { /* parent */
+ ...
+....
+
+Теперь осталось только подключиться к дочернему процессу, установить PauseMode в `0` и дождаться возврата из вызова `sleep()`!
+
+[[emacs]]
+== Использование Emacs в качестве среды разработки
+
+=== Emacs
+
+Emacs — это высоконастраиваемый редактор — настолько, что его можно скорее назвать операционной системой, чем редактором! Многие разработчики и системные администраторы действительно проводят практически всё своё время, работая внутри Emacs, выходя из него только для завершения сеанса.
+
+Невозможно даже кратко описать все, что может делать Emacs, но вот некоторые особенности, которые могут быть интересны разработчикам:
+
+* Очень мощный редактор, позволяющий выполнять поиск и замену как строк, так и регулярных выражений (шаблонов), переход к началу/концу блока выражения и многое другое.
+* Выпадающие меню и встроенная справка.
+* Подсветка синтаксиса и форматирование отступов в зависимости от языка.
+* Полностью настраиваемый.
+* Вы можете компилировать и отлаживать программы из Emacs.
+* При ошибке компиляции можно перейти к проблемной строке исходного кода.
+* Дружелюбный интерфейс для программы `info`, используемой для чтения гипертекстовой документации GNU, включая документацию по самому Emacs.
+* Дружелюбный интерфейс для `gdb`, позволяющий просматривать исходный код во время пошагового выполнения программы.
+
+И, несомненно, множество других, которые были упущены из виду.
+
+Emacs можно установить на FreeBSD с помощью пакета package:editors/emacs[].
+
+После установки запустите его и выполните `C-h t`, чтобы прочитать руководство по Emacs — это означает, что нужно удерживать kbd:[control], нажать kbd:[h], отпустить kbd:[control], а затем нажать kbd:[t]. (Также можно использовать мышь для выбора [.guimenuitem]#Руководство по Emacs# в меню menu:Help[].)
+
+Хотя в Emacs и есть меню, стоит изучить сочетания клавиш, так как редактировать что-либо с их помощью гораздо быстрее, чем искать мышку и кликать в нужное место. Кроме того, общаясь с опытными пользователями Emacs, вы часто услышите выражения вроде «`M-x replace-s RET foo RET bar RET`» — полезно понимать, что они значат. Да и вообще, в Emacs столько полезных функций, что все они просто не поместятся на панелях меню.
+
+К счастью, освоить сочетания клавиш довольно легко, так как они отображаются рядом с пунктами меню. Мой совет — использовать пункты меню для, скажем, открытия файла, пока вы не разберётесь, как это работает, и не почувствуете себя уверенно, а затем попробуйте выполнить `C-x C-f`. Когда освоитесь с этим, переходите к следующей команде меню.
+
+Если вы не можете вспомнить, что делает определённая комбинация клавиш, выберите [.guimenuitem]#Описание Клавиши# в меню menu:Help[] и введите её — Emacs сообщит, что она делает. Вы также можете использовать пункт меню [.guimenuitem]#Command Apropos#, чтобы найти все команды, содержащие определённое слово, с указанием соответствующих клавишных сочетаний.
+
+Между прочим, выражение выше означает: удерживайте клавишу kbd:[Meta], нажмите kbd:[x], отпустите клавишу kbd:[Meta], введите `replace-s` (сокращение от `replace-string` — ещё одна особенность Emacs в том, что команды можно сокращать), нажмите клавишу kbd:[return], введите `foo` (строка, которую нужно заменить), нажмите клавишу kbd:[return], введите `bar` (строка, на которую нужно заменить `foo`) и снова нажмите kbd:[return]. Emacs выполнит операцию поиска и замены, которую вы только что запросили.
+
+Если вам интересно, что такое kbd:[Meta], то это специальная клавиша, которая есть на многих рабочих станциях UNIX(R). К сожалению, на PC её нет, поэтому обычно используется kbd:[alt] (или, если вам не повезло, kbd:[escape]).
+
+Ах да, чтобы выйти из Emacs, нажмите `C-x C-c` (это значит зажмите клавишу kbd:[control], нажмите kbd:[x], затем kbd:[c] и отпустите kbd:[control]). Если у вас есть несохранённые файлы, Emacs спросит, хотите ли вы их сохранить. (Игнорируйте часть документации, где говорится, что `C-z` — это обычный способ выхода из Emacs — это оставляет Emacs работающим в фоне и полезно только на системах без виртуальных терминалов).
+
+=== Настройка Emacs
+
+Emacs делает много замечательных вещей; некоторые из них встроены, некоторые требуют настройки.
+
+Вместо использования проприетарного языка макросов для конфигурации, Emacs применяет версию Lisp, специально адаптированную для редакторов, известную как Emacs Lisp. Работа с Emacs Lisp может быть весьма полезной, если вы хотите продолжить и изучить что-то вроде Common Lisp. Emacs Lisp обладает многими возможностями Common Lisp, хотя и значительно меньше (и, следовательно, проще для освоения).
+
+Лучший способ изучить Emacs Lisp — это прочитать онлайн-руководство link:https://www.gnu.org/software/emacs/manual/elisp.html[Emacs Reference].
+
+Однако для начала настройки Emacs не обязательно знать Lisp, так как я включил пример файла [.filename]#.emacs#, которого должно быть достаточно для старта. Просто скопируйте его в свой домашний каталог и перезапустите Emacs, если он уже запущен; он прочитает команды из файла и (надеюсь) предоставит вам полезную базовую конфигурацию.
+
+=== Пример файла [.filename]#.emacs#
+
+К сожалению, здесь слишком много информации, чтобы объяснять всё подробно; однако есть один или два момента, которые стоит упомянуть.
+
+* Всё, что начинается с `;`, является комментарием и игнорируется Emacs.
+* В первой строке `-*- Emacs-Lisp -*-` нужен для того, чтобы мы могли редактировать сам файл [.filename]#.emacs# в Emacs и использовать все удобные функции для редактирования Emacs Lisp. Обычно Emacs пытается угадать это по имени файла, но может не сделать это правильно для [.filename]#.emacs#.
+* Клавиша kbd:[tab] связана с функцией отступа в некоторых режимах, поэтому при нажатии клавиши tab текущая строка кода будет с отступом. Если вы хотите вставить символ табуляции в текст, удерживайте клавишу kbd:[control] во время нажатия kbd:[tab].
+* Этот файл поддерживает подсветку синтаксиса для C, C++, Perl, Lisp и Scheme, определяя язык по имени файла.
+* В Emacs уже есть предопределённая функция `next-error`. В окне вывода компиляции это позволяет переходить от одной ошибки компиляции к следующей с помощью `M-n`; мы определяем дополнительную функцию `previous-error`, которая позволяет вернуться к предыдущей ошибке с помощью `M-p`. Самое приятное — сочетание `C-c C-c` откроет исходный файл, в котором произошла ошибка, и перейдёт на соответствующую строку.
+* Включаем возможность Emacs работать как сервер, так что если вы заняты чем-то вне Emacs и хотите отредактировать файл, можно просто ввести
++
+[source, bash]
+....
+% emacsclient filename
+....
++
+и затем вы можете редактировать файл в вашем Emacs!footnote:[Многие пользователи Emacs устанавливают переменную окружения EDITOR в emacsclient, так что это происходит каждый раз, когда им нужно отредактировать файл.]
+
+.Пример файла [.filename]#.emacs#
+====
+[.programlisting]
+....
+;; -*-Emacs-Lisp-*-
+
+;; This file is designed to be re-evaled; use the variable first-time
+;; to avoid any problems with this.
+(defvar first-time t
+ "Flag signifying this is the first time that .emacs has been evaled")
+
+;; Meta
+(global-set-key "\M- " 'set-mark-command)
+(global-set-key "\M-\C-h" 'backward-kill-word)
+(global-set-key "\M-\C-r" 'query-replace)
+(global-set-key "\M-r" 'replace-string)
+(global-set-key "\M-g" 'goto-line)
+(global-set-key "\M-h" 'help-command)
+
+;; Function keys
+(global-set-key [f1] 'manual-entry)
+(global-set-key [f2] 'info)
+(global-set-key [f3] 'repeat-complex-command)
+(global-set-key [f4] 'advertised-undo)
+(global-set-key [f5] 'eval-current-buffer)
+(global-set-key [f6] 'buffer-menu)
+(global-set-key [f7] 'other-window)
+(global-set-key [f8] 'find-file)
+(global-set-key [f9] 'save-buffer)
+(global-set-key [f10] 'next-error)
+(global-set-key [f11] 'compile)
+(global-set-key [f12] 'grep)
+(global-set-key [C-f1] 'compile)
+(global-set-key [C-f2] 'grep)
+(global-set-key [C-f3] 'next-error)
+(global-set-key [C-f4] 'previous-error)
+(global-set-key [C-f5] 'display-faces)
+(global-set-key [C-f8] 'dired)
+(global-set-key [C-f10] 'kill-compilation)
+
+;; Keypad bindings
+(global-set-key [up] "\C-p")
+(global-set-key [down] "\C-n")
+(global-set-key [left] "\C-b")
+(global-set-key [right] "\C-f")
+(global-set-key [home] "\C-a")
+(global-set-key [end] "\C-e")
+(global-set-key [prior] "\M-v")
+(global-set-key [next] "\C-v")
+(global-set-key [C-up] "\M-\C-b")
+(global-set-key [C-down] "\M-\C-f")
+(global-set-key [C-left] "\M-b")
+(global-set-key [C-right] "\M-f")
+(global-set-key [C-home] "\M-<")
+(global-set-key [C-end] "\M->")
+(global-set-key [C-prior] "\M-<")
+(global-set-key [C-next] "\M->")
+
+;; Mouse
+(global-set-key [mouse-3] 'imenu)
+
+;; Misc
+(global-set-key [C-tab] "\C-q\t") ; Control tab quotes a tab.
+(setq backup-by-copying-when-mismatch t)
+
+;; Treat 'y' or <CR> as yes, 'n' as no.
+(fset 'yes-or-no-p 'y-or-n-p)
+(define-key query-replace-map [return] 'act)
+(define-key query-replace-map [?\C-m] 'act)
+
+;; Load packages
+(require 'desktop)
+(require 'tar-mode)
+
+;; Pretty diff mode
+(autoload 'ediff-buffers "ediff" "Intelligent Emacs interface to diff" t)
+(autoload 'ediff-files "ediff" "Intelligent Emacs interface to diff" t)
+(autoload 'ediff-files-remote "ediff"
+ "Intelligent Emacs interface to diff")
+
+(if first-time
+ (setq auto-mode-alist
+ (append '(("\\.cpp$" . c++-mode)
+ ("\\.hpp$" . c++-mode)
+ ("\\.lsp$" . lisp-mode)
+ ("\\.scm$" . scheme-mode)
+ ("\\.pl$" . perl-mode)
+ ) auto-mode-alist)))
+
+;; Auto font lock mode
+(defvar font-lock-auto-mode-list
+ (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'lisp-mode 'perl-mode 'scheme-mode)
+ "List of modes to always start in font-lock-mode")
+
+(defvar font-lock-mode-keyword-alist
+ '((c++-c-mode . c-font-lock-keywords)
+ (perl-mode . perl-font-lock-keywords))
+ "Associations between modes and keywords")
+
+(defun font-lock-auto-mode-select ()
+ "Automatically select font-lock-mode if the current major mode is in font-lock-auto-mode-list"
+ (if (memq major-mode font-lock-auto-mode-list)
+ (progn
+ (font-lock-mode t))
+ )
+ )
+
+(global-set-key [M-f1] 'font-lock-fontify-buffer)
+
+;; New dabbrev stuff
+;(require 'new-dabbrev)
+(setq dabbrev-always-check-other-buffers t)
+(setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_")
+(add-hook 'emacs-lisp-mode-hook
+ '(lambda ()
+ (set (make-local-variable 'dabbrev-case-fold-search) nil)
+ (set (make-local-variable 'dabbrev-case-replace) nil)))
+(add-hook 'c-mode-hook
+ '(lambda ()
+ (set (make-local-variable 'dabbrev-case-fold-search) nil)
+ (set (make-local-variable 'dabbrev-case-replace) nil)))
+(add-hook 'text-mode-hook
+ '(lambda ()
+ (set (make-local-variable 'dabbrev-case-fold-search) t)
+ (set (make-local-variable 'dabbrev-case-replace) t)))
+
+;; C++ and C mode...
+(defun my-c++-mode-hook ()
+ (setq tab-width 4)
+ (define-key c++-mode-map "\C-m" 'reindent-then-newline-and-indent)
+ (define-key c++-mode-map "\C-ce" 'c-comment-edit)
+ (setq c++-auto-hungry-initial-state 'none)
+ (setq c++-delete-function 'backward-delete-char)
+ (setq c++-tab-always-indent t)
+ (setq c-indent-level 4)
+ (setq c-continued-statement-offset 4)
+ (setq c++-empty-arglist-indent 4))
+
+(defun my-c-mode-hook ()
+ (setq tab-width 4)
+ (define-key c-mode-map "\C-m" 'reindent-then-newline-and-indent)
+ (define-key c-mode-map "\C-ce" 'c-comment-edit)
+ (setq c-auto-hungry-initial-state 'none)
+ (setq c-delete-function 'backward-delete-char)
+ (setq c-tab-always-indent t)
+;; BSD-ish indentation style
+ (setq c-indent-level 4)
+ (setq c-continued-statement-offset 4)
+ (setq c-brace-offset -4)
+ (setq c-argdecl-indent 0)
+ (setq c-label-offset -4))
+
+;; Perl mode
+(defun my-perl-mode-hook ()
+ (setq tab-width 4)
+ (define-key c++-mode-map "\C-m" 'reindent-then-newline-and-indent)
+ (setq perl-indent-level 4)
+ (setq perl-continued-statement-offset 4))
+
+;; Scheme mode...
+(defun my-scheme-mode-hook ()
+ (define-key scheme-mode-map "\C-m" 'reindent-then-newline-and-indent))
+
+;; Emacs-Lisp mode...
+(defun my-lisp-mode-hook ()
+ (define-key lisp-mode-map "\C-m" 'reindent-then-newline-and-indent)
+ (define-key lisp-mode-map "\C-i" 'lisp-indent-line)
+ (define-key lisp-mode-map "\C-j" 'eval-print-last-sexp))
+
+;; Add all of the hooks...
+(add-hook 'c++-mode-hook 'my-c++-mode-hook)
+(add-hook 'c-mode-hook 'my-c-mode-hook)
+(add-hook 'scheme-mode-hook 'my-scheme-mode-hook)
+(add-hook 'emacs-lisp-mode-hook 'my-lisp-mode-hook)
+(add-hook 'lisp-mode-hook 'my-lisp-mode-hook)
+(add-hook 'perl-mode-hook 'my-perl-mode-hook)
+
+;; Complement to next-error
+(defun previous-error (n)
+ "Visit previous compilation error message and corresponding source code."
+ (interactive "p")
+ (next-error (- n)))
+
+;; Misc...
+(transient-mark-mode 1)
+(setq mark-even-if-inactive t)
+(setq visible-bell nil)
+(setq next-line-add-newlines nil)
+(setq compile-command "make")
+(setq suggest-key-bindings nil)
+(put 'eval-expression 'disabled nil)
+(put 'narrow-to-region 'disabled nil)
+(put 'set-goal-column 'disabled nil)
+(if (>= emacs-major-version 21)
+ (setq show-trailing-whitespace t))
+
+;; Elisp archive searching
+(autoload 'format-lisp-code-directory "lispdir" nil t)
+(autoload 'lisp-dir-apropos "lispdir" nil t)
+(autoload 'lisp-dir-retrieve "lispdir" nil t)
+(autoload 'lisp-dir-verify "lispdir" nil t)
+
+;; Font lock mode
+(defun my-make-face (face color &optional bold)
+ "Create a face from a color and optionally make it bold"
+ (make-face face)
+ (copy-face 'default face)
+ (set-face-foreground face color)
+ (if bold (make-face-bold face))
+ )
+
+(if (eq window-system 'x)
+ (progn
+ (my-make-face 'blue "blue")
+ (my-make-face 'red "red")
+ (my-make-face 'green "dark green")
+ (setq font-lock-comment-face 'blue)
+ (setq font-lock-string-face 'bold)
+ (setq font-lock-type-face 'bold)
+ (setq font-lock-keyword-face 'bold)
+ (setq font-lock-function-name-face 'red)
+ (setq font-lock-doc-string-face 'green)
+ (add-hook 'find-file-hooks 'font-lock-auto-mode-select)
+
+ (setq baud-rate 1000000)
+ (global-set-key "\C-cmm" 'menu-bar-mode)
+ (global-set-key "\C-cms" 'scroll-bar-mode)
+ (global-set-key [backspace] 'backward-delete-char)
+ ; (global-set-key [delete] 'delete-char)
+ (standard-display-european t)
+ (load-library "iso-transl")))
+
+;; X11 or PC using direct screen writes
+(if window-system
+ (progn
+ ;; (global-set-key [M-f1] 'hilit-repaint-command)
+ ;; (global-set-key [M-f2] [?\C-u M-f1])
+ (setq hilit-mode-enable-list
+ '(not text-mode c-mode c++-mode emacs-lisp-mode lisp-mode
+ scheme-mode)
+ hilit-auto-highlight nil
+ hilit-auto-rehighlight 'visible
+ hilit-inhibit-hooks nil
+ hilit-inhibit-rebinding t)
+ (require 'hilit19)
+ (require 'paren))
+ (setq baud-rate 2400) ; For slow serial connections
+ )
+
+;; TTY type terminal
+(if (and (not window-system)
+ (not (equal system-type 'ms-dos)))
+ (progn
+ (if first-time
+ (progn
+ (keyboard-translate ?\C-h ?\C-?)
+ (keyboard-translate ?\C-? ?\C-h)))))
+
+;; Under UNIX
+(if (not (equal system-type 'ms-dos))
+ (progn
+ (if first-time
+ (server-start))))
+
+;; Add any face changes here
+(add-hook 'term-setup-hook 'my-term-setup-hook)
+(defun my-term-setup-hook ()
+ (if (eq window-system 'pc)
+ (progn
+;; (set-face-background 'default "red")
+ )))
+
+;; Restore the "desktop" - do this as late as possible
+(if first-time
+ (progn
+ (desktop-load-default)
+ (desktop-read)))
+
+;; Indicate that this file has been read at least once
+(setq first-time nil)
+
+;; No need to debug anything now
+
+(setq debug-on-error nil)
+
+;; All done
+(message "All done, %s%s" (user-login-name) ".")
+....
+====
+
+=== Расширение списка языков, понимаемых Emacs
+
+Вот, это все хорошо, если вы хотите программировать только на языках, уже предусмотренных в [.filename]#.emacs# (C, C++, Perl, Lisp и Scheme), но что произойдет, если появится новый язык под названием "whizbang", полный захватывающих возможностей?
+
+Первое, что нужно сделать, — это выяснить, поставляются ли с whizbang какие-либо файлы, сообщающие Emacs о языке. Обычно они заканчиваются на [.filename]#.el#, что означает "Emacs Lisp". Например, если whizbang является портом FreeBSD, мы можем найти эти файлы, выполнив
+
+[source, bash]
+....
+% find /usr/ports/lang/whizbang -name "*.el" -print
+....
+
+и установите их, скопировав в каталог Emacs, где находятся файлы Lisp (site Lisp). В FreeBSD это [.filename]#/usr/local/share/emacs/site-lisp#.
+
+Вот пример, если вывод команды find был
+
+[source, bash]
+....
+/usr/ports/lang/whizbang/work/misc/whizbang.el
+....
+
+мы бы сделали
+
+[source, bash]
+....
+# cp /usr/ports/lang/whizbang/work/misc/whizbang.el /usr/local/share/emacs/site-lisp
+....
+
+Далее нам нужно решить, какое расширение имеют исходные файлы whizbang. Допустим, для примера, что все они заканчиваются на [.filename]#.wiz#. Нам необходимо добавить запись в наш [.filename]#.emacs#, чтобы убедиться, что Emacs сможет использовать информацию из [.filename]#whizbang.el#.
+
+Найдите запись auto-mode-alist в файле [.filename]#.emacs# и добавьте строку для whizbang, например:
+
+[.programlisting]
+....
+...
+("\\.lsp$" . lisp-mode)
+("\\.wiz$" . whizbang-mode)
+("\\.scm$" . scheme-mode)
+...
+....
+
+Это означает, что Emacs автоматически перейдёт в режим `whizbang-mode` при редактировании файла с расширением [.filename]#.wiz#.
+
+Непосредственно ниже вы найдете запись font-lock-auto-mode-list. Добавьте `whizbang-mode` в нее следующим образом:
+
+[.programlisting]
+....
+;; Auto font lock mode
+(defvar font-lock-auto-mode-list
+ (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'whizbang-mode 'lisp-mode 'perl-mode 'scheme-mode)
+ "List of modes to always start in font-lock-mode")
+....
+
+Это означает, что Emacs всегда будет включать `font-lock-mode` (т.е. подсветку синтаксиса) при редактировании файла [.filename]#.wiz#.
+
+И это всё, что требуется. Если вам нужно, чтобы что-то ещё выполнялось автоматически при открытии [.filename]#.wiz#, вы можете добавить `whizbang-mode hook` (см. `my-scheme-mode-hook` для простого примера, который добавляет `auto-indent`).
+
+[[tools-reading]]
+== Для дальнейшего ознакомления
+
+Для получения информации о настройке среды разработки для внесения исправлений в саму FreeBSD см. man:development[7].
+
+* Brian Harvey and Matthew Wright _Simply Scheme_ MIT 1994. ISBN 0-262-08226-8
+* Randall Schwartz _Learning Perl_ O'Reilly 1993 ISBN 1-56592-042-2
+* Patrick Henry Winston and Berthold Klaus Paul Horn _Lisp (3rd Edition)_ Addison-Wesley 1989 ISBN 0-201-08319-1
+* Brian W. Kernighan and Rob Pike _The Unix Programming Environment_ Prentice-Hall 1984 ISBN 0-13-937681-X
+* Brian W. Kernighan and Dennis M. Ritchie _The C Programming Language (2nd Edition)_ Prentice-Hall 1988 ISBN 0-13-110362-8
+* Bjarne Stroustrup _The C++ Programming Language_ Addison-Wesley 1991 ISBN 0-201-53992-6
+* W. Richard Stevens _Advanced Programming in the Unix Environment_ Addison-Wesley 1992 ISBN 0-201-56317-7
+* W. Richard Stevens _Unix Network Programming_ Prentice-Hall 1990 ISBN 0-13-949876-1
diff --git a/documentation/content/ru/books/developers-handbook/tools/_index.po b/documentation/content/ru/books/developers-handbook/tools/_index.po
new file mode 100644
index 0000000000..47c68c25ff
--- /dev/null
+++ b/documentation/content/ru/books/developers-handbook/tools/_index.po
@@ -0,0 +1,4483 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# Vladlen Popolitov <vladlenpopolitov@list.ru>, 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2025-10-12 22:16+0300\n"
+"PO-Revision-Date: 2025-07-05 04:45+0000\n"
+"Last-Translator: Vladlen Popolitov <vladlenpopolitov@list.ru>\n"
+"Language-Team: Russian <https://translate-dev.freebsd.org/projects/"
+"documentation/booksdevelopers-handbooktools_index/ru/>\n"
+"Language: ru\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
+"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+"X-Generator: Weblate 4.17\n"
+
+#. type: Title =
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:17
+#, no-wrap
+msgid "Programming Tools"
+msgstr "Инструменты разработки"
+
+#. type: Yaml Front Matter Hash Value: title
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1
+#, no-wrap
+msgid "Chapter 2. Programming Tools"
+msgstr "Глава 2. Инструменты разработки"
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:57
+#, no-wrap
+msgid "Synopsis"
+msgstr "Обзор"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:64
+msgid ""
+"This chapter is an introduction to using some of the programming tools "
+"supplied with FreeBSD, although much of it will be applicable to many other "
+"versions of UNIX(R). It does _not_ attempt to describe coding in any "
+"detail. Most of the chapter assumes little or no previous programming "
+"knowledge, although it is hoped that most programmers will find something of "
+"value in it."
+msgstr ""
+"В этой главе представлено введение в использование некоторых инструментов "
+"для программирования, поставляемых с FreeBSD, хотя многое из описанного "
+"применимо и к другим версиям UNIX(R). Она _не_ претендует на детальное "
+"описание процесса написания кода. Большая часть главы предполагает наличие "
+"минимальных или отсутствие знаний в программировании, хотя предполагается, "
+"что даже опытные программисты найдут в ней что-то полезное."
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:66
+#, no-wrap
+msgid "Introduction"
+msgstr "Введение"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:73
+msgid ""
+"FreeBSD offers an excellent development environment. Compilers for C and C+"
+"+ and an assembler come with the basic system, not to mention classic "
+"UNIX(R) tools such as `sed` and `awk`. If that is not enough, there are "
+"many more compilers and interpreters in the Ports collection. The following "
+"section, crossref:tools[tools-programming,Introduction to Programming], "
+"lists some of the available options. FreeBSD is very compatible with "
+"standards such as POSIX(R) and ANSI C, as well with its own BSD heritage, so "
+"it is possible to write applications that will compile and run with little "
+"or no modification on a wide range of platforms."
+msgstr ""
+"FreeBSD предоставляет отличную среду разработки. Компиляторы для C и C++, а "
+"также ассемблер входят в базовую систему, не говоря уже о классических "
+"инструментах UNIX(R), таких как `sed` и `awk`. Если этого недостаточно, в "
+"коллекции Ports доступно множество других компиляторов и интерпретаторов. В "
+"следующем разделе, crossref:tools[tools-programming,Введение в "
+"программирование], перечислены некоторые из доступных вариантов. FreeBSD "
+"обладает высокой совместимостью со стандартами, такими как POSIX(R) и ANSI "
+"C, а также с собственным наследием BSD, что позволяет создавать приложения, "
+"которые будут компилироваться и запускаться с минимальными изменениями или "
+"без них на широком спектре платформ."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:77
+msgid ""
+"However, all this power can be rather overwhelming at first if you have "
+"never written programs on a UNIX(R) platform before. This document aims to "
+"help you get up and running, without getting too deeply into more advanced "
+"topics. The intention is that this document should give you enough of the "
+"basics to be able to make some sense of the documentation."
+msgstr ""
+"Однако вся эта мощь может поначалу ошеломить, если вы никогда раньше не "
+"писали программы на платформе UNIX(R). Этот документ призван помочь вам "
+"начать работу, не углубляясь слишком сильно в более сложные темы. Цель "
+"заключается в том, чтобы дать вам достаточно базовых знаний для понимания "
+"документации."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:79
+msgid ""
+"Most of the document requires little or no knowledge of programming, "
+"although it does assume a basic competence with using UNIX(R) and a "
+"willingness to learn!"
+msgstr ""
+"Большая часть документа не требует или почти не требует знаний "
+"программирования, хотя предполагает базовые навыки работы с UNIX(R) и "
+"готовность учиться!"
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:81
+#, no-wrap
+msgid "Introduction to Programming"
+msgstr "Введение в программирование"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:87
+msgid ""
+"A program is a set of instructions that tell the computer to do various "
+"things; sometimes the instruction it has to perform depends on what happened "
+"when it performed a previous instruction. This section gives an overview of "
+"the two main ways in which you can give these instructions, or \"commands\" "
+"as they are usually called. One way uses an _interpreter_, the other a "
+"_compiler_. As human languages are too difficult for a computer to "
+"understand in an unambiguous way, commands are usually written in one or "
+"other languages specially designed for the purpose."
+msgstr ""
+"Программа — это набор инструкций, которые указывают компьютеру выполнять "
+"различные действия; иногда выполняемая инструкция зависит от результата "
+"предыдущей. В этом разделе представлен обзор двух основных способов передачи "
+"таких инструкций, или, как их обычно называют, «команд». Один способ "
+"использует _интерпретатор_, другой — _компилятор_. Поскольку человеческие "
+"языки слишком сложны для однозначного понимания компьютером, команды обычно "
+"записываются на одном из специально разработанных для этого языков."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:88
+#, no-wrap
+msgid "Interpreters"
+msgstr "Интерпретаторы"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:93
+msgid ""
+"With an interpreter, the language comes as an environment, where you type in "
+"commands at a prompt and the environment executes them for you. For more "
+"complicated programs, you can type the commands into a file and get the "
+"interpreter to load the file and execute the commands in it. If anything "
+"goes wrong, many interpreters will drop you into a debugger to help you "
+"track down the problem."
+msgstr ""
+"С интерпретатором язык поставляется как среда, в которой вы вводите команды "
+"в приглашении, и среда выполняет их для вас. Для более сложных программ вы "
+"можете ввести команды в файл и заставить интерпретатор загрузить файл и "
+"выполнить команды в нём. Если что-то пойдёт не так, многие интерпретаторы "
+"переведут вас в отладчик, чтобы помочь найти проблему."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:98
+msgid ""
+"The advantage of this is that you can see the results of your commands "
+"immediately, and mistakes can be corrected readily. The biggest "
+"disadvantage comes when you want to share your programs with someone. They "
+"must have the same interpreter, or you must have some way of giving it to "
+"them, and they need to understand how to use it. Also users may not "
+"appreciate being thrown into a debugger if they press the wrong key! From a "
+"performance point of view, interpreters can use up a lot of memory, and "
+"generally do not generate code as efficiently as compilers."
+msgstr ""
+"Преимущество этого подхода в том, что вы сразу видите результаты выполнения "
+"команд, а ошибки можно легко исправить. Самый большой недостаток "
+"проявляется, когда вы хотите поделиться своими программами с кем-то. У них "
+"должен быть такой же интерпретатор, или у вас должен быть способ "
+"предоставить его, и они должны понимать, как им пользоваться. Кроме того, "
+"пользователям может не понравиться, если они попадут в отладчик при нажатии "
+"не той клавиши! С точки зрения производительности интерпретаторы могут "
+"потреблять много памяти и обычно генерируют код менее эффективно, чем "
+"компиляторы."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:103
+msgid ""
+"In my opinion, interpreted languages are the best way to start if you have "
+"not done any programming before. This kind of environment is typically "
+"found with languages like Lisp, Smalltalk, Perl and Basic. It could also be "
+"argued that the UNIX(R) shell (`sh`, `csh`) is itself an interpreter, and "
+"many people do in fact write shell \"scripts\" to help with various "
+"\"housekeeping\" tasks on their machine. Indeed, part of the original "
+"UNIX(R) philosophy was to provide lots of small utility programs that could "
+"be linked together in shell scripts to perform useful tasks."
+msgstr ""
+"По моему мнению, интерпретируемые языки — это лучший способ начать, если вы "
+"раньше не занимались программированием. Такая среда обычно встречается в "
+"языках вроде Lisp, Smalltalk, Perl и Basic. Можно также утверждать, что "
+"UNIX(R) shell (`sh`, `csh`) сам по себе является интерпретатором, и многие "
+"часто пишут shell-«скрипты» для помощи в различных «хозяйственных» задачах "
+"на своих машинах. Действительно, часть оригинальной философии UNIX(R) "
+"заключалась в предоставлении множества небольших утилит, которые можно было "
+"связывать вместе в shell-скриптах для выполнения полезных задач."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:104
+#, no-wrap
+msgid "Interpreters Available with FreeBSD"
+msgstr "Доступные интерпретаторы в FreeBSD"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:107
+msgid ""
+"Here is a list of interpreters that are available from the FreeBSD Ports "
+"Collection, with a brief discussion of some of the more popular interpreted "
+"languages."
+msgstr ""
+"Вот список интерпретаторов, доступных в Коллекции портов FreeBSD, с кратким "
+"обзором некоторых наиболее популярных интерпретируемых языков."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:109
+msgid ""
+"Instructions on how to get and install applications from the Ports "
+"Collection can be found in the extref:{handbook}[Ports section, ports-using] "
+"of the handbook."
+msgstr ""
+"Инструкции по получению и установке приложений из Коллекции портов можно "
+"найти в extref:{handbook}[разделе Порты, ports-using] руководства."
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:110
+#, no-wrap
+msgid "BASIC"
+msgstr "BASIC"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:114
+msgid ""
+"Short for Beginner's All-purpose Symbolic Instruction Code. Developed in "
+"the 1950s for teaching University students to program and provided with "
+"every self-respecting personal computer in the 1980s, BASIC has been the "
+"first programming language for many programmers. It is also the foundation "
+"for Visual Basic."
+msgstr ""
+"Сокращение от Beginner's All-purpose Symbolic Instruction Code. Разработан в "
+"1950-х годах для обучения студентов университетов программированию и "
+"поставлялся с каждым уважающим себя персональным компьютером в 1980-х. BASIC "
+"— первый язык программирования для многих программистов. Он также является "
+"основой для Visual Basic."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:116
+msgid ""
+"The Bywater Basic Interpreter can be found in the Ports Collection as "
+"package:lang/bwbasic[] and the Phil Cockroft's Basic Interpreter (formerly "
+"Rabbit Basic) is available as package:lang/pbasic[]."
+msgstr ""
+"Интерпретатор Bywater Basic можно найти в Коллекции портов как package:lang/"
+"bwbasic[], а интерпретатор Phil Cockroft's Basic (ранее известный как Rabbit "
+"Basic) доступен как package:lang/pbasic[]."
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:117
+#, no-wrap
+msgid "Lisp"
+msgstr "Lisp"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:121
+msgid ""
+"A language that was developed in the late 1950s as an alternative to the "
+"\"number-crunching\" languages that were popular at the time. Instead of "
+"being based on numbers, Lisp is based on lists; in fact, the name is short "
+"for \"List Processing\". It is very popular in AI (Artificial Intelligence) "
+"circles."
+msgstr ""
+"Язык, разработанный в конце 1950-х годов как альтернатива популярным в то "
+"время языкам для «численных расчётов». В отличие от них, Lisp основан на "
+"списках; фактически, название является сокращением от «List Processing» "
+"(обработка списков). Он очень популярен в кругах, связанных с ИИ "
+"(искусственным интеллектом)."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:123
+msgid ""
+"Lisp is an extremely powerful and sophisticated language, but can be rather "
+"large and unwieldy."
+msgstr ""
+"Lisp — это чрезвычайно мощный и сложный язык, но он может показаться "
+"довольно большим и громоздким."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:127
+msgid ""
+"Various implementations of Lisp that can run on UNIX(R) systems are "
+"available in the Ports Collection for FreeBSD. CLISP by Bruno Haible and "
+"Michael Stoll is available as package:lang/clisp[]. SLisp, a simpler Lisp "
+"implementations, is available as package:lang/slisp[]."
+msgstr ""
+"В Коллекции портов FreeBSD доступны различные реализации Lisp, которые могут "
+"работать в системах UNIX(R). CLISP от Bruno Haible и Michael Stoll доступен "
+"как package:lang/clisp[]. Более простая реализация Lisp, SLisp, доступна как "
+"package:lang/slisp[]."
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:128
+#, no-wrap
+msgid "Perl"
+msgstr "Perl"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:130
+msgid ""
+"Very popular with system administrators for writing scripts; also often used "
+"on World Wide Web servers for writing CGI scripts."
+msgstr ""
+"Очень популярен среди системных администраторов для написания скриптов; "
+"также часто используется на веб-серверах для написания CGI-скриптов."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:132
+msgid ""
+"Perl is available in the Ports Collection as package:lang/perl5.36[] for all "
+"FreeBSD releases."
+msgstr ""
+"Perl доступен в Коллекции портов как package:lang/perl5.36[] для всех "
+"выпусков FreeBSD."
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:133
+#, no-wrap
+msgid "Scheme"
+msgstr "Scheme"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:137
+msgid ""
+"A dialect of Lisp that is rather more compact and cleaner than Common Lisp. "
+"Popular in Universities as it is simple enough to teach to undergraduates as "
+"a first language, while it has a high enough level of abstraction to be used "
+"in research work."
+msgstr ""
+"Диалект Lisp, который более компактен и чист по сравнению с Common Lisp. "
+"Популярен в университетах, так как достаточно прост для обучения студентов в "
+"качестве первого языка, и при этом обладает достаточным уровнем абстракции "
+"для использования в исследовательской работе."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:140
+msgid ""
+"Scheme is available from the Ports Collection as package:lang/elk[] for the "
+"Elk Scheme Interpreter. The MIT Scheme Interpreter can be found in "
+"package:lang/mit-scheme[] and the SCM Scheme Interpreter in package:lang/"
+"scm[]."
+msgstr ""
+"Схема доступна из Коллекции Портов как package:lang/elk[] для Интерпретатора "
+"Elk Scheme. Интерпретатор MIT Scheme можно найти в package:lang/mit-"
+"scheme[], а Интерпретатор SCM Scheme — в package:lang/scm[]."
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:141
+#, no-wrap
+msgid "Lua"
+msgstr "Lua"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:147
+msgid ""
+"Lua is a lightweight embeddable scripting language. It is widely portable "
+"and relatively simple. Lua is available in the Ports Collection in "
+"package:lang/lua54[]. It is also included in the base system as "
+"[.filename]#/usr/libexec/flua# for use by base system components. Third "
+"party software should not depend on [.filename]#flua#."
+msgstr ""
+"Lua — это легковесный встраиваемый язык сценариев. Он обладает высокой "
+"переносимостью и относительно прост. Lua доступен в коллекции портов в "
+"пакете package:lang/lua54[]. Он также включен в базовую систему как "
+"[.filename]#/usr/libexec/flua# для использования компонентами базовой "
+"системы. Стороннее программное обеспечение не должно зависеть от "
+"[.filename]#flua#."
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:148
+#, no-wrap
+msgid "Python"
+msgstr "Python"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:151
+msgid ""
+"Python is an Object-Oriented, interpreted language. Its advocates argue "
+"that it is one of the best languages to start programming with, since it is "
+"relatively easy to start with, but is not limited in comparison to other "
+"popular interpreted languages that are used for the development of large, "
+"complex applications (Perl and Tcl are two other languages that are popular "
+"for such tasks)."
+msgstr ""
+"Python — это объектно-ориентированный интерпретируемый язык. Его сторонники "
+"утверждают, что это один из лучших языков для начала программирования, "
+"поскольку он относительно прост в освоении, но не уступает другим популярным "
+"интерпретируемым языкам, используемым для разработки крупных и сложных "
+"приложений (Perl и Tcl — два других языка, популярных для таких задач)."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:153
+msgid ""
+"The latest version of Python is available from the Ports Collection in "
+"package:lang/python[]."
+msgstr ""
+"Последняя версия Python доступна в Коллекции портов в пакете package:lang/"
+"python[]."
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:154
+#, no-wrap
+msgid "Ruby"
+msgstr "Ruby"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:157
+msgid ""
+"Ruby is an interpreter, pure object-oriented programming language. It has "
+"become widely popular because of its easy to understand syntax, flexibility "
+"when writing code, and the ability to easily develop and maintain large, "
+"complex programs."
+msgstr ""
+"Ruby — это интерпретируемый, чисто объектно-ориентированный язык "
+"программирования. Он получил широкую популярность благодаря простому для "
+"понимания синтаксису, гибкости при написании кода и возможности легко "
+"разрабатывать и поддерживать большие, сложные программы."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:159
+msgid "Ruby is available from the Ports Collection as package:lang/ruby32[]."
+msgstr "Ruby доступен в Коллекции портов как package:lang/ruby32[]."
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:160
+#, no-wrap
+msgid "Tcl and Tk"
+msgstr "Tcl и Tk"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:163
+msgid ""
+"Tcl is an embeddable, interpreted language, that has become widely used and "
+"became popular mostly because of its portability to many platforms. It can "
+"be used both for quickly writing small, prototype applications, or (when "
+"combined with Tk, a GUI toolkit) fully-fledged, featureful programs."
+msgstr ""
+"Tcl — это встраиваемый интерпретируемый язык, который получил широкое "
+"распространение и популярность в основном благодаря своей переносимости на "
+"множество платформ. Он может использоваться как для быстрого написания "
+"небольших прототипов приложений, так и (в сочетании с Tk, набором "
+"инструментов для графического интерфейса) полноценных программ с богатым "
+"функционалом."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:166
+msgid ""
+"Various versions of Tcl are available as ports for FreeBSD. The latest "
+"version, Tcl 8.7, can be found in package:lang/tcl87[]."
+msgstr ""
+"Различные версии Tcl доступны в качестве портов для FreeBSD. Последняя "
+"версия, Tcl 8.7, находится в пакете package:lang/tcl87[]."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:167
+#, no-wrap
+msgid "Compilers"
+msgstr "Компиляторы"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:174
+msgid ""
+"Compilers are rather different. First of all, you write your code in a file "
+"(or files) using an editor. You then run the compiler and see if it accepts "
+"your program. If it did not compile, grit your teeth and go back to the "
+"editor; if it did compile and gave you a program, you can run it either at a "
+"shell command prompt or in a debugger to see if it works properly.footnote:"
+"[If you run it in the shell, you may get a core dump.]"
+msgstr ""
+"Компиляторы довольно сильно различаются. Прежде всего, вы пишете свой код в "
+"файле (или файлах) с помощью редактора. Затем вы запускаете компилятор и "
+"проверяете, принимает ли он вашу программу. Если программа не "
+"скомпилировалась, стисните зубы и вернитесь к редактору; если же компиляция "
+"прошла успешно и программа была создана, вы можете запустить её либо в "
+"командной строке оболочки, либо в отладчике, чтобы проверить её "
+"работу.footnote:[Если вы запустите её в оболочке, может произойти дамп "
+"памяти.]"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:181
+msgid ""
+"Obviously, this is not quite as direct as using an interpreter. However it "
+"allows you to do a lot of things which are very difficult or even impossible "
+"with an interpreter, such as writing code which interacts closely with the "
+"operating system-or even writing your own operating system! It is also "
+"useful if you need to write very efficient code, as the compiler can take "
+"its time and optimize the code, which would not be acceptable in an "
+"interpreter. Moreover, distributing a program written for a compiler is "
+"usually more straightforward than one written for an interpreter-you can "
+"just give them a copy of the executable, assuming they have the same "
+"operating system as you."
+msgstr ""
+"Очевидно, это требует больше усилий по сравнению с использованием "
+"интерпретатора. Однако это позволяет делать множество вещей, которые очень "
+"сложны или даже невозможны с интерпретатором, например, писать код, тесно "
+"взаимодействующий с операционной системой — или даже создавать собственную "
+"операционную систему! Это также полезно, если требуется написать очень "
+"эффективный код, так как компилятор может не спешить и оптимизировать код, "
+"что было бы неприемлемо в интерпретаторе. Более того, распространение "
+"программы, написанной для компилятора, обычно проще, чем для интерпретатора "
+"— можно просто предоставить копию исполняемого файла, предполагая, что у "
+"пользователя та же операционная система, что и у вас."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:185
+msgid ""
+"As the edit-compile-run-debug cycle is rather tedious when using separate "
+"programs, many commercial compiler makers have produced Integrated "
+"Development Environments (IDEs for short). FreeBSD does not include an IDE "
+"in the base system, but package:devel/kdevelop[] is available in the Ports "
+"Collection and many use Emacs for this purpose. Using Emacs as an IDE is "
+"discussed in crossref:tools[emacs, Using Emacs as a Development Environment]."
+msgstr ""
+"Поскольку цикл редактирования-компиляции-запуска-отладки довольно утомителен "
+"при использовании отдельных программ, многие производители коммерческих "
+"компиляторов создали интегрированные среды разработки (сокращённо IDE). "
+"FreeBSD не включает IDE в базовую систему, но в Коллекции портов доступен "
+"package:devel/kdevelop[], и многие используют для этой цели Emacs. "
+"Использование Emacs в качестве IDE обсуждается в crossref:tools[emacs, "
+"Использование Emacs как среды разработки]."
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:187
+#, no-wrap
+msgid "Compiling with `cc`"
+msgstr "Компиляция с помощью `cc`"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:192
+msgid ""
+"This section deals with the clang compiler for C and C++, as it's installed "
+"with the FreeBSD base system. Clang is installed as `cc`; the GNU compiler "
+"package:lang/gcc[gcc] is available in the Ports Collection. The details of "
+"producing a program with an interpreter vary considerably between "
+"interpreters, and are usually well covered in the documentation and on-line "
+"help for the interpreter."
+msgstr ""
+"Этот раздел посвящён компилятору clang для языков C и C++, так как он "
+"устанавливается вместе с базовой системой FreeBSD. Clang устанавливается как "
+"`cc`; пакет GNU-компилятора package:lang/gcc[gcc] доступен в Коллекции "
+"портов. Детали создания программы с интерпретатором значительно различаются "
+"в зависимости от интерпретатора и обычно хорошо описаны в документации и "
+"онлайн-справке интерпретатора."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:195
+msgid ""
+"Once you have written your masterpiece, the next step is to convert it into "
+"something that will (hopefully!) run on FreeBSD. This usually involves "
+"several steps, each of which is done by a separate program."
+msgstr ""
+"Как только вы напишете свой шедевр, следующий шаг — преобразовать его во что-"
+"то, что (надеюсь!) будет работать на FreeBSD. Обычно это включает несколько "
+"шагов, каждый из которых выполняется отдельной программой."
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:198
+msgid ""
+"Pre-process your source code to remove comments and do other tricks like "
+"expanding macros in C."
+msgstr ""
+"Обработь исходный код, чтобы удалить комментарии и выполнить другие "
+"действия, такие как раскрытие макросов в C."
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:199
+msgid ""
+"Check the syntax of your code to see if you have obeyed the rules of the "
+"language. If you have not, it will complain!"
+msgstr ""
+"Проверить синтаксис вашего кода, чтобы убедиться, что вы соблюдаете правила "
+"языка. Если нет, он пожалуется!"
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:200
+msgid ""
+"Convert the source code into assembly language-this is very close to machine "
+"code, but still understandable by humans. Allegedly."
+msgstr ""
+"Преобразовать исходный код в ассемблерный язык — это очень близко к "
+"машинному коду, но всё ещё понятно человеку. Как утверждается."
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:201
+msgid ""
+"Convert the assembly language into machine code-yep, we are talking bits and "
+"bytes, ones and zeros here."
+msgstr ""
+"Преобразовать язык ассемблера в машинный код — да, здесь речь идет о битах и "
+"байтах, единицах и нулях."
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:202
+msgid ""
+"Check that you have used things like functions and global variables in a "
+"consistent way. For example, if you have called a non-existent function, it "
+"will complain."
+msgstr ""
+"Проверить, что вы использовали такие элементы, как функции и глобальные "
+"переменные, правильно и последовательно. Например, если вы вызвали "
+"несуществующую функцию, это будет отмечено."
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:203
+msgid ""
+"If you are trying to produce an executable from several source code files, "
+"work out how to fit them all together."
+msgstr ""
+"Если вы пытаетесь создать исполняемый файл из нескольких исходных файлов, "
+"определить, как объединить их все вместе."
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:204
+msgid ""
+"Work out how to produce something that the system's run-time loader will be "
+"able to load into memory and run."
+msgstr ""
+"Определить, как создать что-то, что загрузчик времени выполнения системы "
+"сможет загрузить в память и запустить."
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:205
+msgid "Finally, write the executable on the filesystem."
+msgstr "Наконец, записать исполняемый файл в файловую систему."
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:208
+msgid ""
+"The word _compiling_ is often used to refer to just steps 1 to 4-the others "
+"are referred to as _linking_. Sometimes step 1 is referred to as _pre-"
+"processing_ and steps 3-4 as _assembling_."
+msgstr ""
+"Слово _компиляция_ часто относится только к шагам с 1 по 4, а остальные шаги "
+"называются _линковкой_. Иногда шаг 1 называют _препроцессированием_, а шаги "
+"3-4 — _ассемблированием_."
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:210
+msgid ""
+"Fortunately, almost all this detail is hidden from you, as `cc` is a front "
+"end that manages calling all these programs with the right arguments for "
+"you; simply typing"
+msgstr ""
+"К счастью, почти все эти детали скрыты от вас, так как `cc` — это интерфейс, "
+"который управляет вызовом всех этих программ с правильными аргументами за "
+"вас; достаточно просто набрать"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:214
+#, no-wrap
+msgid "% cc foobar.c\n"
+msgstr "% cc foobar.c\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:218
+msgid ""
+"will cause [.filename]#foobar.c# to be compiled by all the steps above. If "
+"you have more than one file to compile, just do something like"
+msgstr ""
+"и это вызовет компиляцию файла [.filename]#foobar.c# всеми перечисленными "
+"выше шагами. Если у вас несколько файлов для компиляции, просто сделайте что-"
+"то вроде"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:222
+#, no-wrap
+msgid "% cc foo.c bar.c\n"
+msgstr "% cc foo.c bar.c\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:227
+msgid ""
+"Note that the syntax checking is just that - checking the syntax. It will "
+"not check for any logical mistakes you may have made, like putting the "
+"program into an infinite loop, or using a bubble sort when you meant to use "
+"a binary sort.footnote:[In case you did not know, a binary sort is an "
+"efficient way of sorting things into order and a bubble sort is not.]"
+msgstr ""
+"Обратите внимание, что проверка синтаксиса — это всего лишь проверка "
+"синтаксиса. Она не выявит логических ошибок, которые вы могли допустить, "
+"например, создание бесконечного цикла или использование пузырьковой "
+"сортировки вместо бинарной.footnote:[На случай, если вы не знали: бинарная "
+"сортировка — это эффективный способ упорядочивания элементов, в отличие от "
+"пузырьковой.]"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:230
+msgid ""
+"There are lots and lots of options for `cc`, which are all in the manual "
+"page. Here are a few of the most important ones, with examples of how to "
+"use them."
+msgstr ""
+"Существует множество опций для `cc`, все они описаны в руководстве. Вот "
+"несколько наиболее важных из них с примерами использования."
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:231
+#, no-wrap
+msgid "`-o _filename_`"
+msgstr "`-o _filename_`"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:233
+msgid ""
+"The output name of the file. If you do not use this option, `cc` will "
+"produce an executable called [.filename]#a.out#.footnote:[The reasons for "
+"this are buried in the mists of history.]"
+msgstr ""
+"Имя выходного файла. Если вы не используете эту опцию, `cc` создаст "
+"исполняемый файл с именем [.filename]#a.out#.footnote:[Причины этого кроются "
+"в глубинах истории.]"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:238
+#, no-wrap
+msgid ""
+"% cc foobar.c executable is a.out\n"
+"% cc -o foobar foobar.c executable is foobar\n"
+msgstr ""
+"% cc foobar.c executable is a.out\n"
+"% cc -o foobar foobar.c executable is foobar\n"
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:240
+#, no-wrap
+msgid "`-c`"
+msgstr "`-c`"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:243
+msgid ""
+"Just compile the file, do not link it. Useful for toy programs where you "
+"just want to check the syntax, or if you are using a [.filename]#Makefile#."
+msgstr ""
+"Просто скомпилирует файл, не связывая его. Полезно для небольших программ, "
+"где нужно только проверить синтаксис, или если вы используете "
+"[.filename]#Makefile#."
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:247
+#, no-wrap
+msgid "% cc -c foobar.c\n"
+msgstr "% cc -c foobar.c\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:251
+msgid ""
+"This will produce an _object file_ (not an executable) called "
+"[.filename]#foobar.o#. This can be linked together with other object files "
+"into an executable."
+msgstr ""
+"Это создаст _объектный файл_ (не исполняемый) с именем "
+"[.filename]#foobar.o#. Его можно скомпоновать с другими объектными файлами в "
+"исполняемый файл."
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:252
+#, no-wrap
+msgid "`-g`"
+msgstr "`-g`"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:258
+msgid ""
+"Create a debug version of the executable. This makes the compiler put "
+"information into the executable about which line of which source file "
+"corresponds to which function call. A debugger can use this information to "
+"show the source code as you step through the program, which is _very_ "
+"useful; the disadvantage is that all this extra information makes the "
+"program much bigger. Normally, you compile with `-g` while you are "
+"developing a program and then compile a \"release version\" without `-g` "
+"when you are satisfied it works properly."
+msgstr ""
+"Создать отладочную версию исполняемого файла. Это заставляет компилятор "
+"записывать в исполняемый файл информацию о том, какая строка какого "
+"исходного файла соответствует какому вызову функции. Отладчик может "
+"использовать эту информацию для отображения исходного кода при пошаговом "
+"выполнении программы, что _очень_ полезно; недостатком является то, что вся "
+"эта дополнительная информация значительно увеличивает размер программы. "
+"Обычно вы компилируете с `-g` во время разработки программы, а затем "
+"компилируете \"релизную версию\" без `-g`, когда убедитесь, что она работает "
+"правильно."
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:263
+#, no-wrap
+msgid "% cc -g foobar.c\n"
+msgstr "% cc -g foobar.c\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:266
+msgid ""
+"This will produce a debug version of the program. footnote:[Note, we did not "
+"use the -o flag to specify the executable name, so we will get an executable "
+"called a.out. Producing a debug version called foobar is left as an exercise "
+"for the reader!]"
+msgstr ""
+"Это создаст отладочную версию программы. footnote:[Примечание: мы не "
+"использовали флаг -o для указания имени исполняемого файла, поэтому получим "
+"исполняемый файл с именем a.out. Создание отладочной версии с именем foobar "
+"остается упражнением для читателя!]"
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:267
+#, no-wrap
+msgid "`-O`"
+msgstr "`-O`"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:271
+msgid ""
+"Create an optimized version of the executable. The compiler performs "
+"various clever tricks to try to produce an executable that runs faster than "
+"normal. You can add a number after the `-O` to specify a higher level of "
+"optimization, but this often exposes bugs in the compiler's optimizer."
+msgstr ""
+"Создает оптимизированную версию исполняемого файла. Компилятор применяет "
+"различные хитрые приёмы, чтобы попытаться создать исполняемый файл, который "
+"работает быстрее обычного. Вы можете добавить число после `-O`, чтобы "
+"указать более высокий уровень оптимизации, но это часто выявляет ошибки в "
+"оптимизаторе компилятора."
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:275
+#, no-wrap
+msgid "% cc -O -o foobar foobar.c\n"
+msgstr "% cc -O -o foobar foobar.c\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:278
+msgid "This will produce an optimized version of [.filename]#foobar#."
+msgstr "Это создаст оптимизированную версию [.filename]#foobar#."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:281
+msgid ""
+"The following three flags will force `cc` to check that your code complies "
+"to the relevant international standard, often referred to as the ANSI "
+"standard, though strictly speaking it is an ISO standard."
+msgstr ""
+"Следующие три флага заставят `cc` проверять, что ваш код соответствует "
+"соответствующему международному стандарту, часто называемому стандартом "
+"ANSI, хотя строго говоря, это стандарт ISO."
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:282
+#, no-wrap
+msgid "`-Wall`"
+msgstr "`-Wall`"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:285
+msgid ""
+"Enable all the warnings which the authors of `cc` believe are worthwhile. "
+"Despite the name, it will not enable all the warnings `cc` is capable of."
+msgstr ""
+"Включить все предупреждения, которые разработчики `cc` считают полезными. "
+"Несмотря на название, это не включит все предупреждения, которые `cc` "
+"способен выдавать."
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:286
+#, no-wrap
+msgid "`-ansi`"
+msgstr "`-ansi`"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:289
+msgid ""
+"Turn off most, but not all, of the non-ANSI C features provided by `cc`. "
+"Despite the name, it does not guarantee strictly that your code will comply "
+"to the standard."
+msgstr ""
+"Отключит большинство, но не все, не-ANSI C функции, предоставляемые `cc`. "
+"Несмотря на название, это не гарантирует строгого соответствия вашего кода "
+"стандарту."
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:290
+#, no-wrap
+msgid "`-pedantic`"
+msgstr "`-pedantic`"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:292
+msgid "Turn off _all_ ``cc``'s non-ANSI C features."
+msgstr "Отключит _все_ не-ANSI C возможности ``cc``."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:297
+msgid ""
+"Without these flags, `cc` will allow you to use some of its non-standard "
+"extensions to the standard. Some of these are very useful, but will not "
+"work with other compilers - in fact, one of the main aims of the standard is "
+"to allow people to write code that will work with any compiler on any "
+"system. This is known as _portable code_."
+msgstr ""
+"Без этих флагов `cc` позволит вам использовать некоторые из своих "
+"нестандартных расширений стандарта. Некоторые из них очень полезны, но не "
+"будут работать с другими компиляторами — фактически, одна из основных целей "
+"стандарта заключается в том, чтобы позволить людям писать код, который будет "
+"работать с любым компилятором на любой системе. Это известно как "
+"_переносимый код_."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:300
+msgid ""
+"Generally, you should try to make your code as portable as possible, as "
+"otherwise you may have to completely rewrite the program later to get it to "
+"work somewhere else - and who knows what you may be using in a few years "
+"time?"
+msgstr ""
+"Обычно следует стремиться к тому, чтобы ваш код был как можно более "
+"переносимым, иначе позже вам, возможно, придётся полностью переписать "
+"программу для её работы в другом месте — а кто знает, что вы будете "
+"использовать через несколько лет?"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:304
+#, no-wrap
+msgid "% cc -Wall -ansi -pedantic -o foobar foobar.c\n"
+msgstr "% cc -Wall -ansi -pedantic -o foobar foobar.c\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:307
+msgid ""
+"This will produce an executable [.filename]#foobar# after checking "
+"[.filename]#foobar.c# for standard compliance."
+msgstr ""
+"В результате будет создан исполняемый файл [.filename]#foobar# после "
+"проверки [.filename]#foobar.c# на соответствие стандартам."
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:308
+#, no-wrap
+msgid "`-l__library__`"
+msgstr "`-l__library__`"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:310
+msgid "Specify a function library to be used at link time."
+msgstr ""
+"Укажите библиотеку функций, которая будет использоваться во время компоновки."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:313
+msgid ""
+"The most common example of this is when compiling a program that uses some "
+"of the mathematical functions in C. Unlike most other platforms, these are "
+"in a separate library from the standard C one and you have to tell the "
+"compiler to add it."
+msgstr ""
+"Наиболее распространённый пример этого — компиляция программы, использующей "
+"некоторые математические функции в C. В отличие от большинства других "
+"платформ, они находятся в отдельной библиотеке, отличной от стандартной "
+"библиотеки C, и необходимо указать компилятору добавить её."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:317
+msgid ""
+"The rule is that if the library is called [.filename]#libsomething.a#, you "
+"give `cc` the argument `-l__something__`. For example, the math library is "
+"[.filename]#libm.a#, so you give `cc` the argument `-lm`. A common "
+"\"gotcha\" with the math library is that it has to be the last library on "
+"the command line."
+msgstr ""
+"Правило заключается в том, что если библиотека называется "
+"[.filename]#libsomething.a#, то вы передаёте `cc` аргумент `-"
+"l__something__`. Например, математическая библиотека называется "
+"[.filename]#libm.a#, поэтому вы передаёте `cc` аргумент `-lm`. Типичный "
+"подводный камень с математической библиотекой заключается в том, что она "
+"должна быть последней библиотекой в командной строке."
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:321
+#, no-wrap
+msgid "% cc -o foobar foobar.c -lm\n"
+msgstr "% cc -o foobar foobar.c -lm\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:324
+msgid "This will link the math library functions into [.filename]#foobar#."
+msgstr ""
+"Это приведёт к подключению функций математической библиотеки в "
+"[.filename]#foobar#."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:327
+msgid ""
+"If you are compiling C++ code, use {c-plus-plus-command}. {c-plus-plus-"
+"command} can also be invoked as {clang-plus-plus-command} on FreeBSD."
+msgstr ""
+"Если вы компилируете код на C++, используйте {c-plus-plus-command}. {c-plus-"
+"plus-command} также может быть вызван как {clang-plus-plus-command} в "
+"FreeBSD."
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:331
+#, no-wrap
+msgid "% c++ -o foobar foobar.cc\n"
+msgstr "% c++ -o foobar foobar.cc\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:334
+msgid ""
+"This will both produce an executable [.filename]#foobar# from the C++ source "
+"file [.filename]#foobar.cc#."
+msgstr ""
+"Это создаст исполняемый файл [.filename]#foobar# из исходного файла на C++ "
+"[.filename]#foobar.cc#."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:335
+#, no-wrap
+msgid "Common `cc` Queries and Problems"
+msgstr "Распространённые вопросы и проблемы `cc`"
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:337
+#, no-wrap
+msgid "I compiled a file called foobar.c and I cannot find an executable called foobar. Where has it gone?"
+msgstr "Я скомпилировал файл с именем foobar.c и не могу найти исполняемый файл с именем foobar. Куда он пропал?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:341
+msgid ""
+"Remember, `cc` will call the executable [.filename]#a.out# unless you tell "
+"it differently. Use the `-o _filename_` option:"
+msgstr ""
+"Помните, что `cc` вызовет исполняемый файл [.filename]#a.out#, если вы не "
+"укажете иное. Используйте опцию `-o _имя_файла_`:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:345
+#, no-wrap
+msgid "% cc -o foobar foobar.c\n"
+msgstr "% cc -o foobar foobar.c\n"
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:347
+#, no-wrap
+msgid "OK, I have an executable called foobar, I can see it when I run ls, but when I type in foobar at the command prompt it tells me there is no such file. Why can it not find it?"
+msgstr "Хорошо, у меня есть исполняемый файл с именем foobar, я вижу его при выполнении команды ls, но когда я ввожу foobar в командной строке, система сообщает, что такого файла нет. Почему он не может его найти?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:351
+msgid ""
+"Unlike MS-DOS(R), UNIX(R) does not look in the current directory when it is "
+"trying to find out which executable you want it to run, unless you tell it "
+"to. Type `./foobar`, which means \"run the file called [.filename]#foobar# "
+"in the current directory.\""
+msgstr ""
+"В отличие от MS-DOS(R), UNIX(R) не ищет в текущем каталоге, когда пытается "
+"определить, какую программу нужно запустить, если вы явно не укажете это. "
+"Введите `./foobar`, что означает \"запустить файл с именем "
+"[.filename]#foobar# в текущем каталоге.\""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:352
+#, no-wrap
+msgid "I called my executable test, but nothing happens when I run it. What is going on?"
+msgstr "Я назвал свой исполняемый файл test, но при запуске ничего не происходит. В чем дело?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:356
+msgid ""
+"Most UNIX(R) systems have a program called `test` in [.filename]#/usr/bin# "
+"and the shell is picking that one up before it gets to checking the current "
+"directory. Either type:"
+msgstr ""
+"Большинство UNIX(R) систем имеют программу под названием `test` в "
+"[.filename]#/usr/bin#, и оболочка выбирает её, прежде чем проверить текущий "
+"каталог. Введите следующее:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:360
+#, no-wrap
+msgid "% ./test\n"
+msgstr "% ./test\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:363
+msgid "or choose a better name for your program!"
+msgstr "или выберите более подходящее название для вашей программы!"
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:364
+#, no-wrap
+msgid "I compiled my program and it seemed to run all right at first, then there was an error and it said something about core dumped. What does that mean?"
+msgstr "Я скомпилировал свою программу, и сначала она работала нормально, но потом произошла ошибка, и было сообщение о core dumped. Что это значит?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:368
+msgid ""
+"The name _core dump_ dates back to the very early days of UNIX(R), when the "
+"machines used core memory for storing data. Basically, if the program "
+"failed under certain conditions, the system would write the contents of core "
+"memory to disk in a file called [.filename]#core#, which the programmer "
+"could then pore over to find out what went wrong."
+msgstr ""
+"Название _core dump_ восходит к самым ранним дням UNIX(R), когда машины "
+"использовали ферритовую память для хранения данных. По сути, если программа "
+"завершалась сбоем при определённых условиях, система записывала содержимое "
+"ферритовой памяти на диск в файл с именем [.filename]#core#, который "
+"программист затем мог изучить, чтобы выяснить причину ошибки."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:369
+#, no-wrap
+msgid "Fascinating stuff, but what I am supposed to do now?"
+msgstr "Увлекательный материал, но что мне теперь делать?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:372
+msgid ""
+"Use a debugger to analyze the core (see crossref:tools[debugging, "
+"Debugging])."
+msgstr ""
+"Используйте отладчик для анализа образа памяти (см. "
+"crossref:tools[debugging, Отладка])."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:373
+#, no-wrap
+msgid "When my program dumped core, it said something about a segmentation fault. What is that?"
+msgstr "Когда моя программа сбросила core, она сообщила что-то о segmentation fault. Что это?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:377
+msgid ""
+"This basically means that your program tried to perform some sort of illegal "
+"operation on memory; UNIX(R) is designed to protect the operating system and "
+"other programs from rogue programs."
+msgstr ""
+"Это означает, что ваша программа попыталась выполнить какую-то недопустимую "
+"операцию с памятью; UNIX(R) разработана для защиты операционной системы и "
+"других программ от некорректно работающих программ."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:379
+msgid "Common causes for this are:"
+msgstr "Распространенные причины этого:"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:381
+msgid "Trying to write to a NULL pointer, eg"
+msgstr "Попытка записи в NULL-указатель, например:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:386
+#, no-wrap
+msgid ""
+"char *foo = NULL;\n"
+"strcpy(foo, \"bang!\");\n"
+msgstr ""
+"char *foo = NULL;\n"
+"strcpy(foo, \"bang!\");\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:389
+msgid "Using a pointer that has not been initialized, eg"
+msgstr "Использование неинициализированного указателя, например:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:394
+#, no-wrap
+msgid ""
+"char *foo;\n"
+"strcpy(foo, \"bang!\");\n"
+msgstr ""
+"char *foo;\n"
+"strcpy(foo, \"bang!\");\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:398
+msgid ""
+"The pointer will have some random value that, with luck, will point into an "
+"area of memory that is not available to your program and the kernel will "
+"kill your program before it can do any damage. If you are unlucky, it will "
+"point somewhere inside your own program and corrupt one of your data "
+"structures, causing the program to fail mysteriously."
+msgstr ""
+"Указатель будет иметь случайное значение, которое, возможно, укажет на "
+"область памяти, недоступную вашей программе, и ядро завершит вашу программу "
+"до того, как она сможет нанести какой-либо ущерб. Если вам не повезет, он "
+"укажет внутрь вашей собственной программы и повредит одну из структур "
+"данных, что приведет к загадочному сбою программы."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:399
+msgid "Trying to access past the end of an array, eg"
+msgstr "Попытка доступа за пределы массива, например"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:404
+#, no-wrap
+msgid ""
+"int bar[20];\n"
+"bar[27] = 6;\n"
+msgstr ""
+"int bar[20];\n"
+"bar[27] = 6;\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:407
+msgid "Trying to store something in read-only memory, eg"
+msgstr "Попытка сохранить что-то в память только для чтения, например"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:412
+#, no-wrap
+msgid ""
+"char *foo = \"My string\";\n"
+"strcpy(foo, \"bang!\");\n"
+msgstr ""
+"char *foo = \"My string\";\n"
+"strcpy(foo, \"bang!\");\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:415
+msgid ""
+"UNIX(R) compilers often put string literals like `\"My string\"` into read-"
+"only areas of memory."
+msgstr ""
+"Версии UNIX(R) компиляторы часто помещают строковые литералы, такие как "
+"`\"Моя строка\"`, в области памяти только для чтения."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:416
+msgid "Doing naughty things with `malloc()` and `free()`, eg"
+msgstr "Выполнение нежелательных действий с `malloc()` и `free()`, например"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:421
+#, no-wrap
+msgid ""
+"char bar[80];\n"
+"free(bar);\n"
+msgstr ""
+"char bar[80];\n"
+"free(bar);\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:424
+msgid "or"
+msgstr "или"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:430
+#, no-wrap
+msgid ""
+"char *foo = malloc(27);\n"
+"free(foo);\n"
+"free(foo);\n"
+msgstr ""
+"char *foo = malloc(27);\n"
+"free(foo);\n"
+"free(foo);\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:435
+msgid ""
+"Making one of these mistakes will not always lead to an error, but they are "
+"always bad practice. Some systems and compilers are more tolerant than "
+"others, which is why programs that run well on one system can crash when you "
+"try them on another."
+msgstr ""
+"Совершение одной из этих ошибок не всегда приведет к сбою, но это всегда "
+"плохая практика. Некоторые системы и компиляторы более терпимы, чем другие, "
+"поэтому программы, которые хорошо работают на одной системе, могут аварийно "
+"завершаться при попытке запустить их на другой."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:436
+#, no-wrap
+msgid "Sometimes when I get a core dump it says bus error. It says in my UNIX(R) book that this means a hardware problem, but the computer still seems to be working. Is this true?"
+msgstr "Иногда при получении дампа памяти я вижу сообщение ошибки шины (bus error). В моей книге по UNIX(R) сказано, что это означает аппаратную проблему, но компьютер продолжает работать. Это правда?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:440
+msgid ""
+"No, fortunately not (unless of course you really do have a hardware "
+"problem...). This is usually another way of saying that you accessed memory "
+"in a way you should not have."
+msgstr ""
+"Нет, к счастью, нет (если, конечно, у вас действительно нет аппаратной "
+"проблемы...). Обычно это означает, что вы обратились к памяти способом, "
+"который не следует использовать."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:441
+#, no-wrap
+msgid "This dumping core business sounds as though it could be quite useful, if I can make it happen when I want to. Can I do this, or do I have to wait until there is an error?"
+msgstr "Этот процесс создания дампа памяти звучит довольно полезно, если я могу запускать его по своему желанию. Могу ли я это сделать, или нужно ждать возникновения ошибки?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:444
+msgid "Yes, just go to another console or xterm, do"
+msgstr "Можете. Просто перейдите на другую консоль или xterm, выполните"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:448
+#, no-wrap
+msgid "% ps\n"
+msgstr "% ps\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:451
+msgid "to find out the process ID of your program, and do"
+msgstr "чтобы узнать идентификатор процесса вашей программы и выполните"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:455
+#, no-wrap
+msgid "% kill -ABRT pid\n"
+msgstr "% kill -ABRT pid\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:458
+msgid "where `_pid_` is the process ID you looked up."
+msgstr "где `_pid_` — идентификатор процесса, который вы нашли."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:461
+msgid ""
+"This is useful if your program has got stuck in an infinite loop, for "
+"instance. If your program happens to trap SIGABRT, there are several other "
+"signals which have a similar effect."
+msgstr ""
+"Это полезно, если ваша программа зависла в бесконечном цикле, например. Если "
+"ваша программа перехватывает SIGABRT, есть несколько других сигналов, "
+"которые оказывают аналогичный эффект."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:464
+msgid ""
+"Alternatively, you can create a core dump from inside your program, by "
+"calling the `abort()` function. See the manual page of man:abort[3] to "
+"learn more."
+msgstr ""
+"В качестве альтернативы, вы можете создать дамп памяти изнутри вашей "
+"программы, вызвав функцию `abort()`. Дополнительную информацию можно найти "
+"на man:abort[3]."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:467
+msgid ""
+"If you want to create a core dump from outside your program, but do not want "
+"the process to terminate, you can use the `gcore` program. See the manual "
+"page of man:gcore[1] for more information."
+msgstr ""
+"Если вы хотите создать дамп памяти извне вашей программы, но не хотите "
+"завершать процесс, вы можете использовать программу `gcore`. Подробнее см. "
+"на странице руководства man:gcore[1]."
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:469
+#, no-wrap
+msgid "Make"
+msgstr "Make"
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:471
+#, no-wrap
+msgid "What is `make`?"
+msgstr "Что такое `make`?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:474
+msgid ""
+"When you are working on a simple program with only one or two source files, "
+"typing in"
+msgstr ""
+"Когда вы работаете над простой программой с одним или двумя исходными "
+"файлами, вводя"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:478
+#, no-wrap
+msgid "% cc file1.c file2.c\n"
+msgstr "% cc file1.c file2.c\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:481
+msgid ""
+"is not too bad, but it quickly becomes very tedious when there are several "
+"files-and it can take a while to compile, too."
+msgstr ""
+"это не слишком плохо, но быстро становится очень утомительным, когда есть "
+"несколько файлов — и компиляция тоже может занять время."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:484
+msgid ""
+"One way to get around this is to use object files and only recompile the "
+"source file if the source code has changed. So we could have something like:"
+msgstr ""
+"Один из способов обойти это — использовать объектные файлы и "
+"перекомпилировать исходный файл только в случае изменения исходного кода. "
+"Таким образом, у нас может получиться что-то вроде:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:488
+#, no-wrap
+msgid "% cc file1.o file2.o … file37.c …\n"
+msgstr "% cc file1.o file2.o … file37.c …\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:492
+msgid ""
+"if we had changed [.filename]#file37.c#, but not any of the others, since "
+"the last time we compiled. This may speed up the compilation quite a bit, "
+"but does not solve the typing problem."
+msgstr ""
+"если бы мы изменили файл [.filename]#file37.c#, но не трогали остальные с "
+"момента последней компиляции. Это может значительно ускорить компиляцию, но "
+"не решает проблему с вводом."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:494
+msgid ""
+"Or we could write a shell script to solve the typing problem, but it would "
+"have to re-compile everything, making it very inefficient on a large project."
+msgstr ""
+"Или мы могли бы написать shell-скрипт для решения проблемы с вводом, но "
+"тогда пришлось бы перекомпилировать всё, что сделало бы его очень "
+"неэффективным для крупного проекта."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:496
+msgid ""
+"What happens if we have hundreds of source files lying about? What if we are "
+"working in a team with other people who forget to tell us when they have "
+"changed one of their source files that we use?"
+msgstr ""
+"Что произойдет, если у нас есть сотни исходных файлов? Что, если мы работаем "
+"в команде с другими людьми, которые забывают сообщить нам, когда они "
+"изменили один из своих исходных файлов, которые мы используем?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:499
+msgid ""
+"Perhaps we could put the two solutions together and write something like a "
+"shell script that would contain some kind of magic rule saying when a source "
+"file needs compiling. Now all we need now is a program that can understand "
+"these rules, as it is a bit too complicated for the shell."
+msgstr ""
+"Возможно, мы могли бы объединить два решения и написать что-то вроде shell-"
+"скрипта, который содержал бы какое-то волшебное правило, указывающее, когда "
+"исходный файл нужно компилировать. Теперь нам осталось только найти "
+"программу, которая сможет понимать эти правила, так как для shell это "
+"немного слишком сложно."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:504
+msgid ""
+"This program is called `make`. It reads in a file, called a _makefile_, "
+"that tells it how different files depend on each other, and works out which "
+"files need to be re-compiled and which ones do not. For example, a rule "
+"could say something like \"if [.filename]#fromboz.o# is older than "
+"[.filename]#fromboz.c#, that means someone must have changed "
+"[.filename]#fromboz.c#, so it needs to be re-compiled.\" The makefile also "
+"has rules telling make _how_ to re-compile the source file, making it a much "
+"more powerful tool."
+msgstr ""
+"Эта программа называется `make`. Она читает файл, называемый _makefile_, "
+"который указывает, как различные файлы зависят друг от друга, и определяет, "
+"какие файлы нужно перекомпилировать, а какие нет. Например, правило может "
+"звучать так: «если [.filename]#fromboz.o# старше, чем "
+"[.filename]#fromboz.c#, значит, кто-то изменил [.filename]#fromboz.c#, и его "
+"нужно перекомпилировать». В makefile также содержатся правила, указывающие "
+"make, _как_ именно перекомпилировать исходный файл, что делает эту программу "
+"гораздо более мощным инструментом."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:507
+msgid ""
+"Makefiles are typically kept in the same directory as the source they apply "
+"to, and can be called [.filename]#makefile#, [.filename]#Makefile# or "
+"[.filename]#MAKEFILE#. Most programmers use the name [.filename]#Makefile#, "
+"as this puts it near the top of a directory listing, where it can easily be "
+"seen.footnote:[They do not use the MAKEFILE form as block capitals are often "
+"used for documentation files like README.]"
+msgstr ""
+"Файлы Makefile обычно хранятся в том же каталоге, что и исходный код, к "
+"которому они применяются, и могут называться [.filename]#makefile#, "
+"[.filename]#Makefile# или [.filename]#MAKEFILE#. Большинство программистов "
+"используют имя [.filename]#Makefile#, так как это помещает его в начало "
+"списка файлов в каталоге, где его легко заметить.footnote:[Они не используют "
+"форму MAKEFILE, так как заглавные буквы часто применяются для файлов "
+"документации, таких как README.]"
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:508
+#, no-wrap
+msgid "Example of Using `make`"
+msgstr "Пример использования `make`"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:511
+msgid "Here is a very simple make file:"
+msgstr "Вот очень простой файл для make:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:516
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:542
+#, no-wrap
+msgid ""
+"foo: foo.c\n"
+"\tcc -o foo foo.c\n"
+msgstr ""
+"foo: foo.c\n"
+"\tcc -o foo foo.c\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:519
+msgid "It consists of two lines, a dependency line and a creation line."
+msgstr "Он состоит из двух строк: строки зависимости и строки создания."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:526
+msgid ""
+"The dependency line here consists of the name of the program (known as the "
+"_target_), followed by a colon, then whitespace, then the name of the source "
+"file. When `make` reads this line, it looks to see if [.filename]#foo# "
+"exists; if it exists, it compares the time [.filename]#foo# was last "
+"modified to the time [.filename]#foo.c# was last modified. If "
+"[.filename]#foo# does not exist, or is older than [.filename]#foo.c#, it "
+"then looks at the creation line to find out what to do. In other words, "
+"this is the rule for working out when [.filename]#foo.c# needs to be re-"
+"compiled."
+msgstr ""
+"Строка зависимости здесь состоит из имени программы (известного как _цель_), "
+"за которым следует двоеточие, пробел и имя исходного файла. Когда `make` "
+"читает эту строку, он проверяет, существует ли файл [.filename]#foo#; если "
+"он существует, программа сравнивает время последнего изменения файла "
+"[.filename]#foo# с временем последнего изменения файла [.filename]#foo.c#. "
+"Если файл [.filename]#foo# не существует или старше файла "
+"[.filename]#foo.c#, программа смотрит на строку создания, чтобы выяснить, "
+"что делать. Другими словами, это правило для определения, когда файл "
+"[.filename]#foo.c# нужно перекомпилировать."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:530
+msgid ""
+"The creation line starts with a tab (press kbd:[tab]) and then the command "
+"you would type to create [.filename]#foo# if you were doing it at a command "
+"prompt. If [.filename]#foo# is out of date, or does not exist, `make` then "
+"executes this command to create it. In other words, this is the rule which "
+"tells make how to re-compile [.filename]#foo.c#."
+msgstr ""
+"Строка создания начинается с табуляции (нажмите kbd:[tab]), а затем следует "
+"команда, которую вы бы ввели для создания [.filename]#foo#, если бы делали "
+"это в командной строке. Если [.filename]#foo# устарел или не существует, "
+"`make` выполняет эту команду для его создания. Другими словами, это правило, "
+"которое сообщает make, как перекомпилировать [.filename]#foo.c#."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:534
+msgid ""
+"So, when you type `make`, it will make sure that [.filename]#foo# is up to "
+"date with respect to your latest changes to [.filename]#foo.c#. This "
+"principle can be extended to [.filename]#Makefile#'s with hundreds of "
+"targets-in fact, on FreeBSD, it is possible to compile the entire operating "
+"system just by typing `make buildworld buildkernel` at the top level "
+"directory in the src tree."
+msgstr ""
+"Таким образом, при вводе команды `make` система обеспечит актуальность файла "
+"[.filename]#foo# относительно последних изменений в [.filename]#foo.c#. Этот "
+"принцип можно распространить на [.filename]#Makefile#, содержащие сотни "
+"целей — фактически, в FreeBSD можно собрать всю операционную систему, просто "
+"введя `make buildworld buildkernel` в корневом каталоге дерева исходных "
+"кодов (src)."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:537
+msgid ""
+"Another useful property of makefiles is that the targets do not have to be "
+"programs. For instance, we could have a make file that looks like this:"
+msgstr ""
+"Еще одно полезное свойство makefile заключается в том, что цели не "
+"обязательно должны быть программами. Например, у нас может быть makefile, "
+"который выглядит так:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:545
+#, no-wrap
+msgid ""
+"install:\n"
+"\tcp foo /home/me\n"
+msgstr ""
+"install:\n"
+"\tcp foo /home/me\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:548
+msgid "We can tell make which target we want to make by typing:"
+msgstr "Мы можем указать make, какую цель мы хотим собрать, набрав:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:552
+#, no-wrap
+msgid "% make target\n"
+msgstr "% make target\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:556
+msgid ""
+"`make` will then only look at that target and ignore any others. For "
+"example, if we type `make foo` with the makefile above, make will ignore the "
+"`install` target."
+msgstr ""
+"`make` будет рассматривать только указанную цель и игнорировать все "
+"остальные. Например, если мы введём `make foo` с указанным выше makefile, "
+"make проигнорирует цель `install`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:559
+msgid ""
+"If we just type `make` on its own, make will always look at the first target "
+"and then stop without looking at any others. So if we typed `make` here, it "
+"will just go to the `foo` target, re-compile [.filename]#foo# if necessary, "
+"and then stop without going on to the `install` target."
+msgstr ""
+"Если мы просто введем `make` без параметров, make всегда будет обращаться к "
+"первой цели и затем остановится, не рассматривая остальные. Поэтому если мы "
+"введем `make` здесь, он просто перейдет к цели `foo`, перекомпилирует "
+"[.filename]#foo# при необходимости и затем остановится, не переходя к цели "
+"`install`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:563
+msgid ""
+"Notice that the `install` target does not actually depend on anything! This "
+"means that the command on the following line is always executed when we try "
+"to make that target by typing `make install`. In this case, it will copy "
+"[.filename]#foo# into the user's home directory. This is often used by "
+"application makefiles, so that the application can be installed in the "
+"correct directory when it has been correctly compiled."
+msgstr ""
+"Обратите внимание, что цель `install` не зависит ни от чего! Это означает, "
+"что команда в следующей строке всегда выполняется при попытке создать эту "
+"цель с помощью команды `make install`. В данном случае она скопирует "
+"[.filename]#foo# в домашний каталог пользователя. Это часто используется в "
+"makefile приложений, чтобы приложение можно было установить в правильный "
+"каталог после успешной компиляции."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:568
+msgid ""
+"This is a slightly confusing subject to try to explain. If you do not quite "
+"understand how `make` works, the best thing to do is to write a simple "
+"program like \"hello world\" and a make file like the one above and "
+"experiment. Then progress to using more than one source file, or having the "
+"source file include a header file. `touch` is very useful here-it changes "
+"the date on a file without you having to edit it."
+msgstr ""
+"Это немного запутанная тема для объяснения. Если вы не до конца понимаете, "
+"как работает `make`, лучше всего написать простую программу, например, "
+"\"hello world\", и make-файл, как указано выше, и поэкспериментировать. "
+"Затем можно перейти к использованию нескольких исходных файлов или "
+"добавлению заголовочного файла в исходный код. В этом случае очень полезен "
+"`touch` — он изменяет дату файла без необходимости его редактирования."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:569
+#, no-wrap
+msgid "Make and include-files"
+msgstr "make и include-файлы"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:573
+msgid ""
+"C code often starts with a list of files to include, for example stdio.h. "
+"Some of these files are system-include files, some of them are from the "
+"project you are now working on:"
+msgstr ""
+"Код на C часто начинается со списка подключаемых файлов, например stdio.h. "
+"Некоторые из этих файлов являются системными, а некоторые принадлежат "
+"текущему проекту:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:578
+#, no-wrap
+msgid ""
+"#include <stdio.h>\n"
+"#include \"foo.h\"\n"
+msgstr ""
+"#include <stdio.h>\n"
+"#include \"foo.h\"\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:580
+#, no-wrap
+msgid "int main(....\n"
+msgstr "int main(....\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:583
+msgid ""
+"To make sure that this file is recompiled the moment [.filename]#foo.h# is "
+"changed, you have to add it in your [.filename]#Makefile#:"
+msgstr ""
+"Чтобы убедиться, что этот файл перекомпилируется при изменении "
+"[.filename]#foo.h#, необходимо добавить его в [.filename]#Makefile#:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:587
+#, no-wrap
+msgid "foo: foo.c foo.h\n"
+msgstr "foo: foo.c foo.h\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:594
+msgid ""
+"The moment your project is getting bigger and you have more and more own "
+"include-files to maintain, it will be a pain to keep track of all include "
+"files and the files which are depending on it. If you change an include-"
+"file but forget to recompile all the files which are depending on it, the "
+"results will be devastating. `clang` has an option to analyze your files "
+"and to produce a list of include-files and their dependencies: `-MM`."
+msgstr ""
+"В момент, когда ваш проект становится больше и у вас появляется все больше "
+"собственных включаемых файлов для поддержки, отслеживание всех включаемых "
+"файлов и файлов, которые от них зависят, становится проблемой. Если вы "
+"измените включаемый файл, но забудете перекомпилировать все файлы, которые "
+"от него зависят, последствия будут катастрофическими. У `clang` есть опция "
+"для анализа ваших файлов и создания списка включаемых файлов и их "
+"зависимостей: `-MM`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:596
+msgid "If you add this to your Makefile:"
+msgstr "Если вы добавите это в ваш Makefile:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:601
+#, no-wrap
+msgid ""
+"depend:\n"
+"\tcc -E -MM *.c > .depend\n"
+msgstr ""
+"depend:\n"
+"\tcc -E -MM *.c > .depend\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:604
+msgid ""
+"and run `make depend`, the file [.filename]#.depend# will appear with a list "
+"of object-files, C-files and the include-files:"
+msgstr ""
+"и выполните `make depend`, появится файл [.filename]#.depend# со списком "
+"объектных файлов, C-файлов и включаемых файлов:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:608
+#, no-wrap
+msgid "foo.o: foo.c foo.h\n"
+msgstr "foo.o: foo.c foo.h\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:611
+msgid ""
+"If you change [.filename]#foo.h#, next time you run `make` all files "
+"depending on [.filename]#foo.h# will be recompiled."
+msgstr ""
+"Если вы измените файл [.filename]#foo.h#, при следующем запуске `make` все "
+"файлы, зависящие от [.filename]#foo.h#, будут перекомпилированы."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:613
+msgid ""
+"Do not forget to run `make depend` each time you add an include-file to one "
+"of your files."
+msgstr ""
+"Не забудьте выполнить `make depend` каждый раз, когда вы добавляете include-"
+"файл в один из своих файлов."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:614
+#, no-wrap
+msgid "FreeBSD Makefiles"
+msgstr "Файлы Makefile системы FreeBSD"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:620
+msgid ""
+"Makefiles can be rather complicated to write. Fortunately, BSD-based "
+"systems like FreeBSD come with some very powerful ones as part of the "
+"system. One very good example of this is the FreeBSD ports system. Here is "
+"the essential part of a typical ports [.filename]#Makefile#:"
+msgstr ""
+"Makefile-ы могут быть довольно сложными для написания. К счастью, в BSD-"
+"системах, таких как FreeBSD, есть очень мощные Makefile-ы, поставляемые в "
+"составе системы. Отличным примером этого является система портов FreeBSD. "
+"Вот основная часть типичного [.filename]#Makefile# для портов:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:625
+#, no-wrap
+msgid ""
+"MASTER_SITES= ftp://freefall.cdrom.com/pub/FreeBSD/LOCAL_PORTS/\n"
+"DISTFILES= scheme-microcode+dist-7.3-freebsd.tgz\n"
+msgstr ""
+"MASTER_SITES= ftp://freefall.cdrom.com/pub/FreeBSD/LOCAL_PORTS/\n"
+"DISTFILES= scheme-microcode+dist-7.3-freebsd.tgz\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:627
+#, no-wrap
+msgid ".include <bsd.port.mk>\n"
+msgstr ".include <bsd.port.mk>\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:630
+msgid ""
+"Now, if we go to the directory for this port and type `make`, the following "
+"happens:"
+msgstr ""
+"Теперь, если мы перейдем в каталог этого порта и наберем `make`, произойдет "
+"следующее:"
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:633
+msgid ""
+"A check is made to see if the source code for this port is already on the "
+"system."
+msgstr "Проверяется, есть ли исходный код этого порта уже в системе."
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:634
+msgid ""
+"If it is not, an FTP connection to the URL in MASTER_SITES is set up to "
+"download the source."
+msgstr ""
+"Если это не так, устанавливается FTP-соединение с URL в MASTER_SITES для "
+"загрузки исходного кода."
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:635
+msgid ""
+"The checksum for the source is calculated and compared it with one for a "
+"known, good, copy of the source. This is to make sure that the source was "
+"not corrupted while in transit."
+msgstr ""
+"Контрольная сумма исходного кода вычисляется и сравнивается с контрольной "
+"суммой известной и хорошей копии исходного кода. Это делается для того, "
+"чтобы убедиться, что исходный код не был поврежден во время передачи."
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:636
+msgid ""
+"Any changes required to make the source work on FreeBSD are applied-this is "
+"known as _patching_."
+msgstr ""
+"Все необходимые изменения для адаптации исходного кода к работе в FreeBSD "
+"применяются — это называется применением _патча_."
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:637
+msgid ""
+"Any special configuration needed for the source is done. (Many UNIX(R) "
+"program distributions try to work out which version of UNIX(R) they are "
+"being compiled on and which optional UNIX(R) features are present-this is "
+"where they are given the information in the FreeBSD ports scenario)."
+msgstr ""
+"Любая необходимая специальная настройка для исходного кода выполнена. "
+"(Многие дистрибутивы программ UNIX(R) пытаются определить, на какой версии "
+"UNIX(R) они компилируются и какие дополнительные функции UNIX(R) доступны — "
+"именно здесь они получают эту информацию в сценарии портов FreeBSD)."
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:638
+msgid ""
+"The source code for the program is compiled. In effect, we change to the "
+"directory where the source was unpacked and do `make`-the program's own make "
+"file has the necessary information to build the program."
+msgstr ""
+"Компилируется исходный код программы. По сути, мы переходим в каталог, куда "
+"были распакованы исходные файлы, и выполняем `make` — собственный make-файл "
+"программы содержит необходимую информацию для сборки программы."
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:639
+msgid ""
+"We now have a compiled version of the program. If we wish, we can test it "
+"now; when we feel confident about the program, we can type `make install`. "
+"This will cause the program and any supporting files it needs to be copied "
+"into the correct location; an entry is also made into a `package database`, "
+"so that the port can easily be uninstalled later if we change our mind about "
+"it."
+msgstr ""
+"Теперь у нас есть скомпилированная версия программы. При желании мы можем "
+"протестировать её сейчас; когда мы уверены в программе, можно ввести `make "
+"install`. Это приведёт к копированию программы и всех необходимых "
+"вспомогательных файлов в нужные места, а также к добавлению записи в `базу "
+"данных пакетов`, чтобы позже можно было легко удалить порт, если мы "
+"передумаем."
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:641
+msgid ""
+"Now I think you will agree that is rather impressive for a four line script!"
+msgstr ""
+"Вот теперь, я думаю, вы согласитесь, что это довольно впечатляюще для "
+"скрипта из четырёх строк!"
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:645
+msgid ""
+"The secret lies in the last line, which tells `make` to look in the system "
+"makefile called [.filename]#bsd.port.mk#. It is easy to overlook this line, "
+"but this is where all the clever stuff comes from-someone has written a "
+"makefile that tells `make` to do all the things above (plus a couple of "
+"other things I did not mention, including handling any errors that may "
+"occur) and anyone can get access to that just by putting a single line in "
+"their own make file!"
+msgstr ""
+"Секрет кроется в последней строке, которая указывает `make` обратиться к "
+"системному makefile под названием [.filename]#bsd.port.mk#. Эту строку легко "
+"пропустить, но именно здесь начинается вся магия — кто-то написал makefile, "
+"который предписывает `make` выполнить все вышеперечисленные действия (плюс "
+"несколько других, которые я не упомянул, включая обработку возможных "
+"ошибок), и любой может получить доступ к этому функционалу, просто добавив "
+"одну строку в свой собственный makefile!"
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:649
+msgid ""
+"If you want to have a look at these system makefiles, they are in "
+"[.filename]#/usr/share/mk#, but it is probably best to wait until you have "
+"had a bit of practice with makefiles, as they are very complicated (and if "
+"you do look at them, make sure you have a flask of strong coffee handy!)"
+msgstr ""
+"Если вы хотите взглянуть на эти системные makefile-ы, они находятся в "
+"[.filename]#/usr/share/mk#, но, вероятно, лучше подождать, пока у вас не "
+"появится немного практики с makefile, так как они очень сложные (и если вы "
+"всё же решите их посмотреть, убедитесь, что у вас под рукой есть фляга "
+"крепкого кофе!)"
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:650
+#, no-wrap
+msgid "More Advanced Uses of `make`"
+msgstr "Более сложные способы использования `make`"
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:656
+msgid ""
+"`Make` is a very powerful tool, and can do much more than the simple example "
+"above shows. Unfortunately, there are several different versions of `make`, "
+"and they all differ considerably. The best way to learn what they can do is "
+"probably to read the documentation-hopefully this introduction will have "
+"given you a base from which you can do this. The man:make[1] manual page "
+"offers a comprehensive discussion of variables, arguments, and how to use "
+"make."
+msgstr ""
+"`Make` — это очень мощный инструмент, способный на гораздо большее, чем "
+"показано в простом примере выше. К сожалению, существует несколько различных "
+"версий `make`, и все они значительно отличаются друг от друга. Лучший способ "
+"узнать, на что они способны, — вероятно, прочитать документацию. Надеюсь, "
+"это введение дало вам основу, с которой вы сможете это сделать. В "
+"man:make[1] подробно обсуждаются переменные, аргументы и то, как "
+"использовать `make`."
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:660
+msgid ""
+"Many applications in the ports use GNU make, which has a very good set of "
+"\"info\" pages. If you have installed any of these ports, GNU make will "
+"automatically have been installed as `gmake`. It is also available as a "
+"port and package in its own right."
+msgstr ""
+"Многие приложения в портах используют GNU make, который имеет очень хороший "
+"набор страниц \"info\". Если вы установили любой из этих портов, GNU make "
+"будет автоматически установлен как `gmake`. Он также доступен как отдельный "
+"порт и пакет."
+
+#. type: .procedure
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:663
+msgid ""
+"To view the info pages for GNU make, you will have to edit [.filename]#dir# "
+"in the [.filename]#/usr/local/info# directory to add an entry for it. This "
+"involves adding a line like"
+msgstr ""
+"Для просмотра справочных страниц (info) GNU make вам потребуется "
+"отредактировать файл [.filename]#dir# в каталоге [.filename]#/usr/local/"
+"info#, добавив соответствующую запись. Добавьте строку"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:667
+#, no-wrap
+msgid " * Make: (make). The GNU Make utility.\n"
+msgstr " * Make: (make). The GNU Make utility.\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:670
+msgid ""
+"to the file. Once you have done this, you can type `info` and then select "
+"[.guimenuitem]#make# from the menu (or in Emacs, do `C-h i`)."
+msgstr ""
+"в файл. После этого вы можете ввести `info` и затем выбрать "
+"[.guimenuitem]#make# из меню (или в Emacs выполнить `C-h i`)."
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:672
+#, no-wrap
+msgid "Debugging"
+msgstr "Отладка"
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:674
+#, no-wrap
+msgid "Introduction to Available Debuggers"
+msgstr "Обзор отладчиков, поставляемых в системе"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:679
+msgid ""
+"Using a debugger allows running the program under more controlled "
+"circumstances. Typically, it is possible to step through the program a line "
+"at a time, inspect the value of variables, change them, tell the debugger to "
+"run up to a certain point and then stop, and so on. It is also possible to "
+"attach to a program that is already running, or load a core file to "
+"investigate why the program crashed."
+msgstr ""
+"Использование отладчика позволяет запускать программу в более контролируемых "
+"условиях. Обычно можно выполнять программу построчно, проверять значения "
+"переменных, изменять их, указывать отладчику выполнение до определённой "
+"точки и затем останавливаться и так далее. Также можно подключиться к уже "
+"работающей программе или загрузить core-файл, чтобы исследовать причину "
+"аварийного завершения программы."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:682
+msgid ""
+"This section is intended to be a quick introduction to using debuggers and "
+"does not cover specialized topics such as debugging the kernel. For more "
+"information about that, refer to crossref:kerneldebug[kerneldebug,Kernel "
+"Debugging]."
+msgstr ""
+"Этот раздел представляет собой краткое введение в использование отладчиков и "
+"не затрагивает специализированные темы, такие как отладка ядра. Для "
+"получения дополнительной информации по этой теме обратитесь к главе "
+"crossref:kerneldebug[kerneldebug,Отладка ядра]."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:686
+msgid ""
+"The standard debugger supplied with FreeBSD is called `lldb` (LLVM "
+"debugger). As it is part of the standard installation for that release, "
+"there is no need to do anything special to use it. It has good command "
+"help, accessible via the `help` command, as well as https://lldb.llvm.org/[a "
+"web tutorial and documentation]."
+msgstr ""
+"Стандартный отладчик, поставляемый с FreeBSD, называется `lldb` (LLVM "
+"debugger). Поскольку он является частью стандартной установки для данного "
+"выпуска, нет необходимости выполнять какие-либо дополнительные действия для "
+"его использования. Он обладает хорошей справкой по командам, доступной через "
+"команду `help`, а также https://lldb.llvm.org/[руководством и документацией "
+"в интернете]."
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:690
+msgid ""
+"The `lldb` command is also available extref:{handbook}ports/[from ports or "
+"packages, ports-using] as package:devel/llvm[]."
+msgstr ""
+"Команда `lldb` также доступна extref:{handbook}ports/[из портов или пакетов, "
+"ports-using] как пакет package:devel/llvm[]."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:696
+msgid ""
+"The other debugger available with FreeBSD is called `gdb` (GNU debugger). "
+"Unlike lldb, it is not installed by default on FreeBSD; to use it, extref:"
+"{handbook}#ports-using/[install] package:devel/gdb[] from ports or "
+"packages. It has excellent on-line help, as well as a set of info pages."
+msgstr ""
+"Другой отладчик, доступный в FreeBSD, называется `gdb` (GNU debugger). В "
+"отличие от lldb, он не устанавливается по умолчанию в FreeBSD; для его "
+"использования необходимо extref:{handbook}#ports-using/[установить] пакет "
+"package:devel/gdb[] из портов или пакетов. Он обладает отличной встроенной "
+"справкой, а также набором info-страниц."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:701
+msgid ""
+"The two debuggers have a similar feature set, so which one to use is largely "
+"a matter of taste. If familiar with one only, use that one. People "
+"familiar with neither or both but wanting to use one from inside Emacs will "
+"need to use `gdb` as `lldb` is unsupported by Emacs. Otherwise, try both "
+"and see which one you prefer."
+msgstr ""
+"Два отладчика обладают схожим набором функций, поэтому выбор между ними в "
+"основном зависит от личных предпочтений. Если вы знакомы только с одним из "
+"них, используйте его. Тем, кто не знаком ни с одним или знаком с обоими, но "
+"хочет использовать отладчик внутри Emacs, придётся выбрать `gdb`, так как "
+"`lldb` не поддерживается Emacs. В остальных случаях попробуйте оба и решите, "
+"какой вам больше нравится."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:702
+#, no-wrap
+msgid "Using lldb"
+msgstr "Использование lldb"
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:704
+#, no-wrap
+msgid "Starting lldb"
+msgstr "Запуск lldb"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:707
+msgid "Start up lldb by typing"
+msgstr "Запустите lldb, набрав"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:711
+#, no-wrap
+msgid "% lldb -- progname\n"
+msgstr "% lldb -- progname\n"
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:713
+#, no-wrap
+msgid "Running a Program with lldb"
+msgstr "Запуск программы с lldb"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:718
+msgid ""
+"Compile the program with `-g` to get the most out of using `lldb`. It will "
+"work without, but will only display the name of the function currently "
+"running, instead of the source code. If it displays a line like:"
+msgstr ""
+"Скомпилируйте программу с `-g`, чтобы максимально использовать возможности "
+"`lldb`. Без этого флаг она будет работать, но отображать только имя текущей "
+"выполняемой функции вместо исходного кода. Если отображается строка вида:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:722
+#, no-wrap
+msgid "Breakpoint 1: where = temp`main, address = …\n"
+msgstr "Breakpoint 1: where = temp`main, address = …\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:725
+msgid ""
+"(without an indication of source code filename and line number) when setting "
+"a breakpoint, this means that the program was not compiled with `-g`."
+msgstr ""
+"(без указания имени файла исходного кода и номера строки) при установке "
+"точки останова это означает, что программа не была скомпилирована с "
+"параметром `-g`."
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:730
+msgid ""
+"Most `lldb` commands have shorter forms that can be used instead. The "
+"longer forms are used here for clarity."
+msgstr ""
+"Большинство команд `lldb` имеют более короткие формы, которые можно "
+"использовать вместо полных. Здесь используются полные формы для ясности."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:735
+msgid ""
+"At the `lldb` prompt, type `breakpoint set -n main`. This will tell the "
+"debugger not to display the preliminary set-up code in the program being run "
+"and to stop execution at the beginning of the program's code. Now type "
+"`process launch` to actually start the program- it will start at the "
+"beginning of the set-up code and then get stopped by the debugger when it "
+"calls `main()`."
+msgstr ""
+"На строке `lldb` введите `breakpoint set -n main`. Это укажет отладчику не "
+"показывать предварительный код настройки в запускаемой программе и "
+"остановить выполнение в начале кода программы. Теперь введите `process "
+"launch`, чтобы фактически запустить программу — она начнётся с кода "
+"настройки, а затем будет остановлена отладчиком при вызове `main()`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:739
+msgid ""
+"To step through the program a line at a time, type `thread step-over`. When "
+"the program gets to a function call, step into it by typing `thread step-"
+"in`. Once in a function call, return from it by typing `thread step-out` or "
+"use `up` and `down` to take a quick look at the caller."
+msgstr ""
+"Для пошагового выполнения программы строка за строкой введите `thread step-"
+"over`. Когда программа дойдёт до вызова функции, войдите в неё, набрав "
+"`thread step-in`. Оказавшись внутри вызова функции, вернитесь из него с "
+"помощью команды `thread step-out` или используйте `up` и `down`, чтобы "
+"быстро посмотреть на вызывающий код."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:742
+msgid ""
+"Here is a simple example of how to spot a mistake in a program with `lldb`. "
+"This is our program (with a deliberate mistake):"
+msgstr ""
+"Вот простой пример того, как найти ошибку в программе с помощью `lldb`. Это "
+"наша программа (с умышленной ошибкой):"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:746
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1020
+#, no-wrap
+msgid "#include <stdio.h>\n"
+msgstr "#include <stdio.h>\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:748
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1022
+#, no-wrap
+msgid "int bazz(int anint);\n"
+msgstr "int bazz(int anint);\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:751
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1025
+#, no-wrap
+msgid ""
+"main() {\n"
+"\tint i;\n"
+msgstr ""
+"main() {\n"
+"\tint i;\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:756
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1030
+#, no-wrap
+msgid ""
+"\tprintf(\"This is my program\\n\");\n"
+"\tbazz(i);\n"
+"\treturn 0;\n"
+"}\n"
+msgstr ""
+"\tprintf(\"This is my program\\n\");\n"
+"\tbazz(i);\n"
+"\treturn 0;\n"
+"}\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:761
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1035
+#, no-wrap
+msgid ""
+"int bazz(int anint) {\n"
+"\tprintf(\"You gave me %d\\n\", anint);\n"
+"\treturn anint;\n"
+"}\n"
+msgstr ""
+"int bazz(int anint) {\n"
+"\tprintf(\"You gave me %d\\n\", anint);\n"
+"\treturn anint;\n"
+"}\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:764
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1038
+msgid ""
+"This program sets i to be `5` and passes it to a function `bazz()` which "
+"prints out the number we gave it."
+msgstr ""
+"Эта программа устанавливает значение `i` равным `5` и передает его в функцию "
+"`bazz()`, которая выводит переданное число."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:766
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1040
+msgid "Compiling and running the program displays"
+msgstr "Компиляция и запуск программы отображают"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:773
+#, no-wrap
+msgid ""
+"% cc -g -o temp temp.c\n"
+"% ./temp\n"
+"This is my program\n"
+"anint = -5360\n"
+msgstr ""
+"% cc -g -o temp temp.c\n"
+"% ./temp\n"
+"This is my program\n"
+"anint = -5360\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:776
+msgid "That is not what was expected! Time to see what is going on!"
+msgstr "Это не то, что ожидалось! Пора разобраться, что происходит!"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:787
+#, no-wrap
+msgid ""
+"% lldb -- temp\n"
+"(lldb) target create \"temp\"\n"
+"Current executable set to 'temp' (x86_64).\n"
+"(lldb) breakpoint set -n main\t\t\t\tSkip the set-up code\n"
+"Breakpoint 1: where = temp`main + 15 at temp.c:8:2, address = 0x00000000002012ef\tlldb puts breakpoint at main()\n"
+"(lldb) process launch\t\t\t\t\tRun as far as main()\n"
+"Process 9992 launching\n"
+"Process 9992 launched: '/home/pauamma/tmp/temp' (x86_64)\tProgram starts running\n"
+msgstr ""
+"% lldb -- temp\n"
+"(lldb) target create \"temp\"\n"
+"Current executable set to 'temp' (x86_64).\n"
+"(lldb) breakpoint set -n main\t\t\t\tSkip the set-up code\n"
+"Breakpoint 1: where = temp`main + 15 at temp.c:8:2, address = 0x00000000002012ef\tlldb puts breakpoint at main()\n"
+"(lldb) process launch\t\t\t\t\tRun as far as main()\n"
+"Process 9992 launching\n"
+"Process 9992 launched: '/home/pauamma/tmp/temp' (x86_64)\tProgram starts running\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:821
+#, no-wrap
+msgid ""
+"Process 9992 stopped\n"
+"* thread #1, name = 'temp', stop reason = breakpoint 1.1\tlldb stops at main()\n"
+" frame #0: 0x00000000002012ef temp`main at temp.c:8:2\n"
+" 5\tmain() {\n"
+" 6\t\tint i;\n"
+" 7\n"
+"-> 8\t\tprintf(\"This is my program\\n\");\t\t\tIndicates the line where it stopped\n"
+" 9\t\tbazz(i);\n"
+" 10\t\treturn 0;\n"
+" 11\t}\n"
+"(lldb) thread step-over\t\t\tGo to next line\n"
+"This is my program\t\t\t\t\t\tProgram prints out\n"
+"Process 9992 stopped\n"
+"* thread #1, name = 'temp', stop reason = step over\n"
+" frame #0: 0x0000000000201300 temp`main at temp.c:9:7\n"
+" 6\t\tint i;\n"
+" 7\n"
+" 8\t\tprintf(\"This is my program\\n\");\n"
+"-> 9\t\tbazz(i);\n"
+" 10\t\treturn 0;\n"
+" 11\t}\n"
+" 12\n"
+"(lldb) thread step-in\t\t\tstep into bazz()\n"
+"Process 9992 stopped\n"
+"* thread #1, name = 'temp', stop reason = step in\n"
+" frame #0: 0x000000000020132b temp`bazz(anint=-5360) at temp.c:14:29\tlldb displays stack frame\n"
+" 11\t}\n"
+" 12\n"
+" 13\tint bazz(int anint) {\n"
+"-> 14\t\tprintf(\"You gave me %d\\n\", anint);\n"
+" 15\t\treturn anint;\n"
+" 16\t}\n"
+"(lldb)\n"
+msgstr ""
+"Process 9992 stopped\n"
+"* thread #1, name = 'temp', stop reason = breakpoint 1.1\tlldb stops at main()\n"
+" frame #0: 0x00000000002012ef temp`main at temp.c:8:2\n"
+" 5\tmain() {\n"
+" 6\t\tint i;\n"
+" 7\n"
+"-> 8\t\tprintf(\"This is my program\\n\");\t\t\tIndicates the line where it stopped\n"
+" 9\t\tbazz(i);\n"
+" 10\t\treturn 0;\n"
+" 11\t}\n"
+"(lldb) thread step-over\t\t\tGo to next line\n"
+"This is my program\t\t\t\t\t\tProgram prints out\n"
+"Process 9992 stopped\n"
+"* thread #1, name = 'temp', stop reason = step over\n"
+" frame #0: 0x0000000000201300 temp`main at temp.c:9:7\n"
+" 6\t\tint i;\n"
+" 7\n"
+" 8\t\tprintf(\"This is my program\\n\");\n"
+"-> 9\t\tbazz(i);\n"
+" 10\t\treturn 0;\n"
+" 11\t}\n"
+" 12\n"
+"(lldb) thread step-in\t\t\tstep into bazz()\n"
+"Process 9992 stopped\n"
+"* thread #1, name = 'temp', stop reason = step in\n"
+" frame #0: 0x000000000020132b temp`bazz(anint=-5360) at temp.c:14:29\tlldb displays stack frame\n"
+" 11\t}\n"
+" 12\n"
+" 13\tint bazz(int anint) {\n"
+"-> 14\t\tprintf(\"You gave me %d\\n\", anint);\n"
+" 15\t\treturn anint;\n"
+" 16\t}\n"
+"(lldb)\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:824
+msgid ""
+"Hang on a minute! How did anint get to be `-5360`? Was it not set to `5` in "
+"`main()`? Let us move up to `main()` and have a look."
+msgstr ""
+"Подождите минуту! Как переменная `int` стала равна `-5360`? Разве она не "
+"была установлена в `5` в `main()`? Давайте поднимемся к `main()` и посмотрим."
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:838
+#, no-wrap
+msgid ""
+"(lldb) up\t\tMove up call stack\n"
+"frame #1: 0x000000000020130b temp`main at temp.c:9:2\t\tlldb displays stack frame\n"
+" 6\t\tint i;\n"
+" 7\n"
+" 8\t\tprintf(\"This is my program\\n\");\n"
+"-> 9\t\tbazz(i);\n"
+" 10\t\treturn 0;\n"
+" 11\t}\n"
+" 12\n"
+"(lldb) frame variable i\t\t\tShow us the value of i\n"
+"(int) i = -5360\t\t\t\t\t\t\tlldb displays -5360\n"
+msgstr ""
+"(lldb) up\t\tMove up call stack\n"
+"frame #1: 0x000000000020130b temp`main at temp.c:9:2\t\tlldb displays stack frame\n"
+" 6\t\tint i;\n"
+" 7\n"
+" 8\t\tprintf(\"This is my program\\n\");\n"
+"-> 9\t\tbazz(i);\n"
+" 10\t\treturn 0;\n"
+" 11\t}\n"
+" 12\n"
+"(lldb) frame variable i\t\t\tShow us the value of i\n"
+"(int) i = -5360\t\t\t\t\t\t\tlldb displays -5360\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:842
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1083
+msgid ""
+"Oh dear! Looking at the code, we forgot to initialize i. We meant to put"
+msgstr "О боже! Глядя на код, мы забыли инициализировать i. Мы хотели добавить"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:848
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1089
+#, no-wrap
+msgid ""
+"...\n"
+"main() {\n"
+"\tint i;\n"
+msgstr ""
+"...\n"
+"main() {\n"
+"\tint i;\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:852
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1093
+#, no-wrap
+msgid ""
+"\ti = 5;\n"
+"\tprintf(\"This is my program\\n\");\n"
+"...\n"
+msgstr ""
+"\ti = 5;\n"
+"\tprintf(\"This is my program\\n\");\n"
+"...\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:857
+msgid ""
+"but we left the `i=5;` line out. As we did not initialize i, it had "
+"whatever number happened to be in that area of memory when the program ran, "
+"which in this case happened to be `-5360`."
+msgstr ""
+"но мы пропустили строку `i=5;`. Поскольку мы не инициализировали `i`, она "
+"содержала любое число, которое оказалось в той области памяти при запуске "
+"программы, и в данном случае это оказалось `-5360`."
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:863
+msgid ""
+"The `lldb` command displays the stack frame every time we go into or out of "
+"a function, even if we are using `up` and `down` to move around the call "
+"stack. This shows the name of the function and the values of its arguments, "
+"which helps us keep track of where we are and what is going on. (The stack "
+"is a storage area where the program stores information about the arguments "
+"passed to functions and where to go when it returns from a function call.)"
+msgstr ""
+"Команда `lldb` отображает стек вызовов каждый раз, когда мы входим в функцию "
+"или выходим из неё, даже если мы используем `up` и `down` для перемещения по "
+"стеку вызовов. Это показывает имя функции и значения её аргументов, что "
+"помогает отслеживать текущее положение и происходящее. (Стек — это область "
+"хранения, где программа сохраняет информацию об аргументах, переданных в "
+"функции, и о том, куда возвращаться после вызова функции.)"
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:865
+#, no-wrap
+msgid "Examining a Core File with lldb"
+msgstr "Изучение файла Core с помощью lldb"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:870
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1111
+msgid ""
+"A core file is basically a file which contains the complete state of the "
+"process when it crashed. In \"the good old days\", programmers had to print "
+"out hex listings of core files and sweat over machine code manuals, but now "
+"life is a bit easier. Incidentally, under FreeBSD and other 4.4BSD systems, "
+"a core file is called [.filename]#progname.core# instead of just "
+"[.filename]#core#, to make it clearer which program a core file belongs to."
+msgstr ""
+"Файл core — это, по сути, файл, содержащий полное состояние процесса на "
+"момент его аварийного завершения. В «старые добрые времена» программистам "
+"приходилось распечатывать шестнадцатеричные дампы файлов core и корпеть над "
+"руководствами по машинному коду, но сейчас жизнь стала немного проще. "
+"Кстати, в FreeBSD и других системах на базе 4.4BSD файл core называется "
+"[.filename]#progname.core#, а не просто [.filename]#core#, чтобы было "
+"понятнее, какой программе он принадлежит."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:873
+msgid ""
+"To examine a core file, specify the name of the core file in addition to the "
+"program itself. Instead of starting up `lldb` in the usual way, type `lldb "
+"-c _progname_.core \\-- _progname_`."
+msgstr ""
+"Для анализа файла core укажите имя файла core в дополнение к самой "
+"программе. Вместо обычного запуска `lldb` введите `lldb -c "
+"_имя_программы_.core \\-- _имя_программы_`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:875
+msgid "The debugger will display something like this:"
+msgstr "Отладчик отобразит что-то вроде этого:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:882
+#, no-wrap
+msgid ""
+"% lldb -c [.filename]#progname.core# -- [.filename]#progname#\n"
+"(lldb) target create \"[.filename]#progname#\" --core \"[.filename]#progname#.core\"\n"
+"Core file '/home/pauamma/tmp/[.filename]#progname.core#' (x86_64) was loaded.\n"
+"(lldb)\n"
+msgstr ""
+"% lldb -c [.filename]#progname.core# -- [.filename]#progname#\n"
+"(lldb) target create \"[.filename]#progname#\" --core \"[.filename]#progname#.core\"\n"
+"Core file '/home/pauamma/tmp/[.filename]#progname.core#' (x86_64) was loaded.\n"
+"(lldb)\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:888
+msgid ""
+"In this case, the program was called [.filename]#progname#, so the core file "
+"is called [.filename]#progname.core#. The debugger does not display why the "
+"program crashed or where. For this, use `thread backtrace all`. This will "
+"also show how the function where the program dumped core was called."
+msgstr ""
+"В этом случае программа называлась [.filename]#progname#, поэтому файл дампа "
+"имеет имя [.filename]#progname.core#. Отладчик не показывает, почему "
+"программа завершилась аварийно или где это произошло. Для этого используйте "
+"команду `thread backtrace all`. Она также покажет, как была вызвана функция, "
+"в которой программа завершилась дампом ядра."
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:897
+#, no-wrap
+msgid ""
+"(lldb) thread backtrace all\n"
+"* thread #1, name = 'progname', stop reason = signal SIGSEGV\n"
+" * frame #0: 0x0000000000201347 progname`bazz(anint=5) at temp2.c:17:10\n"
+" frame #1: 0x0000000000201312 progname`main at temp2.c:10:2\n"
+" frame #2: 0x000000000020110f progname`_start(ap=<unavailable>, cleanup=<unavailable>) at crt1.c:76:7\n"
+"(lldb)\n"
+msgstr ""
+"(lldb) thread backtrace all\n"
+"* thread #1, name = 'progname', stop reason = signal SIGSEGV\n"
+" * frame #0: 0x0000000000201347 progname`bazz(anint=5) at temp2.c:17:10\n"
+" frame #1: 0x0000000000201312 progname`main at temp2.c:10:2\n"
+" frame #2: 0x000000000020110f progname`_start(ap=<unavailable>, cleanup=<unavailable>) at crt1.c:76:7\n"
+"(lldb)\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:902
+msgid ""
+"`SIGSEGV` indicates that the program tried to access memory (run code or "
+"read/write data usually) at a location that does not belong to it, but does "
+"not give any specifics. For that, look at the source code at line 10 of "
+"file temp2.c, in `bazz()`. The backtrace also says that in this case, "
+"`bazz()` was called from `main()`."
+msgstr ""
+"`SIGSEGV` указывает, что программа пыталась получить доступ к памяти (обычно "
+"выполнить код или прочитать/записать данные) по адресу, который ей не "
+"принадлежит, но не предоставляет конкретных деталей. Для этого обратитесь к "
+"исходному коду на строке 10 файла temp2.c, в функции `bazz()`. Трассировка "
+"также показывает, что в данном случае `bazz()` была вызвана из `main()`."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:903
+#, no-wrap
+msgid "Attaching to a Running Program with lldb"
+msgstr "Подключение к работающей программе с помощью lldb"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:908
+msgid ""
+"One of the neatest features about `lldb` is that it can attach to a program "
+"that is already running. Of course, that requires sufficient permissions to "
+"do so. A common problem is stepping through a program that forks and "
+"wanting to trace the child, but the debugger will only trace the parent."
+msgstr ""
+"Одной из самых замечательных особенностей `lldb` является возможность "
+"подключения к уже работающей программе. Конечно, для этого требуются "
+"соответствующие разрешения. Распространённая проблема — пошаговое выполнение "
+"программы, которая создаёт ответвления, с необходимостью отслеживать "
+"дочерний процесс, но отладчик отслеживает только родительский."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:910
+msgid ""
+"To do that, start up another `lldb`, use `ps` to find the process ID for the "
+"child, and do"
+msgstr ""
+"Для этого запустите другой `lldb`, используйте `ps` для поиска "
+"идентификатора процесса дочернего процесса и выполните"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:914
+#, no-wrap
+msgid "(lldb) process attach -p pid\n"
+msgstr "(lldb) process attach -p pid\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:917
+msgid "in `lldb`, and then debug as usual."
+msgstr "в `lldb`, а затем отлаживайте как обычно."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:919
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1174
+msgid ""
+"For that to work well, the code that calls `fork` to create the child needs "
+"to do something like the following (courtesy of the `gdb` info pages):"
+msgstr ""
+"Для того чтобы это работало правильно, код, который вызывает `fork` для "
+"создания дочернего процесса, должен делать что-то вроде следующего "
+"(предоставлено из документации `gdb`):"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:927
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1182
+#, no-wrap
+msgid ""
+"...\n"
+"if ((pid = fork()) < 0)\t\t/* _Always_ check this */\n"
+"\terror();\n"
+"else if (pid == 0) {\t\t/* child */\n"
+"\tint PauseMode = 1;\n"
+msgstr ""
+"...\n"
+"if ((pid = fork()) < 0)\t\t/* _Always_ check this */\n"
+"\terror();\n"
+"else if (pid == 0) {\t\t/* child */\n"
+"\tint PauseMode = 1;\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:933
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1188
+#, no-wrap
+msgid ""
+"\twhile (PauseMode)\n"
+"\t\tsleep(10);\t/* Wait until someone attaches to us */\n"
+"\t...\n"
+"} else {\t\t\t/* parent */\n"
+"\t...\n"
+msgstr ""
+"\twhile (PauseMode)\n"
+"\t\tsleep(10);\t/* Wait until someone attaches to us */\n"
+"\t...\n"
+"} else {\t\t\t/* parent */\n"
+"\t...\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:936
+msgid ""
+"Now all that is needed is to attach to the child, set PauseMode to `0` with "
+"`expr PauseMode = 0` and wait for the `sleep()` call to return."
+msgstr ""
+"Вот все, что нужно сделать: подключиться к дочернему процессу, установить "
+"`PauseMode` в `0` с помощью `expr PauseMode = 0` и дождаться возврата из "
+"вызова `sleep()`."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:937
+#, no-wrap
+msgid "Remote Debugging Using LLDB"
+msgstr "Удаленная отладка с использованием LLDB"
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:943
+msgid ""
+"The described functionality is available starting with LLDB version 12.0.0. "
+"Users of FreeBSD releases containing an earlier LLDB version may wish to use "
+"the snapshot available in extref:{handbook}[ports or packages, ports-using], "
+"as package:devel/llvm-devel[]."
+msgstr ""
+"Описанная функциональность доступна начиная с версии LLDB 12.0.0. "
+"Пользователи релизов FreeBSD, содержащих более раннюю версию LLDB, могут "
+"воспользоваться снимком из extref:{handbook}[портов или пакетов, ports-"
+"using], как package:devel/llvm-devel[]."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:947
+msgid ""
+"Starting with LLDB 12.0.0, remote debugging is supported on FreeBSD. This "
+"means that `lldb-server` can be started to debug a program on one host, "
+"while the interactive `lldb` client connects to it from another one."
+msgstr ""
+"Начиная с LLDB 12.0.0, удалённая отладка поддерживается в FreeBSD. Это "
+"означает, что `lldb-server` может быть запущен для отладки программы на "
+"одном узле, в то время как интерактивный клиент `lldb` подключается к нему с "
+"другого."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:949
+msgid ""
+"To launch a new process to be debugged remotely, run `lldb-server` on the "
+"remote server by typing"
+msgstr ""
+"Чтобы запустить новый процесс для удалённой отладки, выполните `lldb-server` "
+"на удалённом сервере, набрав"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:953
+#, no-wrap
+msgid "% lldb-server g host:port -- progname\n"
+msgstr "% lldb-server g host:port -- progname\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:956
+msgid ""
+"The process will be stopped immediately after launching, and `lldb-server` "
+"will wait for the client to connect."
+msgstr ""
+"Процесс будет остановлен сразу после запуска, и `lldb-server` будет ожидать "
+"подключения клиента."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:958
+msgid ""
+"Start `lldb` locally and type the following command to connect to the remote "
+"server:"
+msgstr ""
+"Запустите `lldb` локально и введите следующую команду для подключения к "
+"удалённому серверу:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:962
+#, no-wrap
+msgid "(lldb) gdb-remote host:port\n"
+msgstr "(lldb) gdb-remote host:port\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:966
+msgid ""
+"`lldb-server` can also attach to a running process. To do that, type the "
+"following on the remote server:"
+msgstr ""
+"`lldb-server` также может присоединиться к работающему процессу. Для этого "
+"введите следующее на удалённом сервере:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:970
+#, no-wrap
+msgid "% lldb-server g host:port --attach pid-or-name\n"
+msgstr "% lldb-server g host:port --attach pid-or-name\n"
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:972
+#, no-wrap
+msgid "Using gdb"
+msgstr "Использование gdb"
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:974
+#, no-wrap
+msgid "Starting gdb"
+msgstr "Запуск gdb"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:977
+msgid "Start up gdb by typing"
+msgstr "Запустите gdb, набрав"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:981
+#, no-wrap
+msgid "% gdb progname\n"
+msgstr "% gdb progname\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:985
+msgid "although many people prefer to run it inside Emacs. To do this, type:"
+msgstr ""
+"хотя многие предпочитают запускать его внутри Emacs. Для этого введите:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:989
+#, no-wrap
+msgid " M-x gdb RET progname RET\n"
+msgstr " M-x gdb RET progname RET\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:992
+msgid ""
+"Finally, for those finding its text-based command-prompt style off-putting, "
+"there is a graphical front-end for it (package:devel/xxgdb[]) in the Ports "
+"Collection."
+msgstr ""
+"Наконец, для тех, кого отпугивает текстовый интерфейс командной строки, "
+"существует графический интерфейс (package:devel/xxgdb[]) в Коллекции портов."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:993
+#, no-wrap
+msgid "Running a Program with gdb"
+msgstr "Запуск программы под отладчиком gdb"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:998
+msgid ""
+"Compile the program with `-g` to get the most out of using `gdb`. It will "
+"work without, but will only display the name of the function currently "
+"running, instead of the source code. A line like:"
+msgstr ""
+"Скомпилируйте программу с `-g`, чтобы максимально использовать возможности "
+"`gdb`. Она будет работать и без этого, но отобразит только имя текущей "
+"выполняемой функции вместо исходного кода. Строка вида:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1002
+#, no-wrap
+msgid "... (no debugging symbols found) ...\n"
+msgstr "... (no debugging symbols found) ...\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1005
+msgid "when `gdb` starts up means that the program was not compiled with `-g`."
+msgstr ""
+"когда `gdb` запускается, это означает, что программа не была скомпилирована "
+"с опцией `-g`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1009
+msgid ""
+"At the `gdb` prompt, type `break main`. This will tell the debugger to skip "
+"the preliminary set-up code in the program being run and to stop execution "
+"at the beginning of the program's code. Now type `run` to start the "
+"program- it will start at the beginning of the set-up code and then get "
+"stopped by the debugger when it calls `main()`."
+msgstr ""
+"На приглашении `gdb` введите `break main`. Это укажет отладчику пропустить "
+"предварительный код настройки в выполняемой программе и остановить "
+"выполнение в начале кода программы. Теперь введите `run`, чтобы запустить "
+"программу — она начнётся с начала кода настройки, а затем будет остановлена "
+"отладчиком при вызове `main()`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1013
+msgid ""
+"To step through the program a line at a time, press `n`. When at a function "
+"call, step into it by pressing `s`. Once in a function call, return from it "
+"by pressing `f`, or use `up` and `down` to take a quick look at the caller."
+msgstr ""
+"Для пошагового выполнения программы нажимайте `n`. При вызове функции "
+"войдите в неё, нажав `s`. Оказавшись внутри функции, вернитесь из неё, нажав "
+"`f`, или используйте `up` и `down` для быстрого просмотра вызывающего кода."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1016
+msgid ""
+"Here is a simple example of how to spot a mistake in a program with `gdb`. "
+"This is our program (with a deliberate mistake):"
+msgstr ""
+"Вот простой пример того, как найти ошибку в программе с помощью `gdb`. Это "
+"наша программа (с умышленной ошибкой):"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1047
+#, no-wrap
+msgid ""
+"% cc -g -o temp temp.c\n"
+"% ./temp\n"
+"This is my program\n"
+"anint = 4231\n"
+msgstr ""
+"% cc -g -o temp temp.c\n"
+"% ./temp\n"
+"This is my program\n"
+"anint = 4231\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1050
+msgid "That was not what we expected! Time to see what is going on!"
+msgstr "Это было не то, что мы ожидали! Пора разобраться, что происходит!"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1062
+#, no-wrap
+msgid ""
+"% gdb temp\n"
+"GDB is free software and you are welcome to distribute copies of it\n"
+" under certain conditions; type \"show copying\" to see the conditions.\n"
+"There is absolutely no warranty for GDB; type \"show warranty\" for details.\n"
+"GDB 4.13 (i386-unknown-freebsd), Copyright 1994 Free Software Foundation, Inc.\n"
+"(gdb) break main\t\t\t\tSkip the set-up code\n"
+"Breakpoint 1 at 0x160f: file temp.c, line 9.\tgdb puts breakpoint at main()\n"
+"(gdb) run\t\t\t\t\tRun as far as main()\n"
+"Starting program: /home/james/tmp/temp\t\tProgram starts running\n"
+msgstr ""
+"% gdb temp\n"
+"GDB is free software and you are welcome to distribute copies of it\n"
+" under certain conditions; type \"show copying\" to see the conditions.\n"
+"There is absolutely no warranty for GDB; type \"show warranty\" for details.\n"
+"GDB 4.13 (i386-unknown-freebsd), Copyright 1994 Free Software Foundation, Inc.\n"
+"(gdb) break main\t\t\t\tSkip the set-up code\n"
+"Breakpoint 1 at 0x160f: file temp.c, line 9.\tgdb puts breakpoint at main()\n"
+"(gdb) run\t\t\t\t\tRun as far as main()\n"
+"Starting program: /home/james/tmp/temp\t\tProgram starts running\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1069
+#, no-wrap
+msgid ""
+"Breakpoint 1, main () at temp.c:9\t\tgdb stops at main()\n"
+"(gdb) n\t\t\t\t\t\tGo to next line\n"
+"This is my program\t\t\t\tProgram prints out\n"
+"(gdb) s\t\t\t\t\t\tstep into bazz()\n"
+"bazz (anint=4231) at temp.c:17\t\t\tgdb displays stack frame\n"
+"(gdb)\n"
+msgstr ""
+"Breakpoint 1, main () at temp.c:9\t\tgdb stops at main()\n"
+"(gdb) n\t\t\t\t\t\tGo to next line\n"
+"This is my program\t\t\t\tProgram prints out\n"
+"(gdb) s\t\t\t\t\t\tstep into bazz()\n"
+"bazz (anint=4231) at temp.c:17\t\t\tgdb displays stack frame\n"
+"(gdb)\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1072
+msgid ""
+"Hang on a minute! How did anint get to be `4231`? Was it not set to `5` in "
+"`main()`? Let us move up to `main()` and have a look."
+msgstr ""
+"Подождите минуту! Как `int` стал равен `4231`? Разве он не был установлен в "
+"`5` в `main()`? Давайте поднимемся к `main()` и посмотрим."
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1079
+#, no-wrap
+msgid ""
+"(gdb) up\t\t\t\t\tMove up call stack\n"
+"#1 0x1625 in main () at temp.c:11\t\tgdb displays stack frame\n"
+"(gdb) p i\t\t\t\t\tShow us the value of i\n"
+"$1 = 4231\t\t\t\t\tgdb displays 4231\n"
+msgstr ""
+"(gdb) up\t\t\t\t\tMove up call stack\n"
+"#1 0x1625 in main () at temp.c:11\t\tgdb displays stack frame\n"
+"(gdb) p i\t\t\t\t\tShow us the value of i\n"
+"$1 = 4231\t\t\t\t\tgdb displays 4231\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1098
+msgid ""
+"but we left the `i=5;` line out. As we did not initialize i, it had "
+"whatever number happened to be in that area of memory when the program ran, "
+"which in this case happened to be `4231`."
+msgstr ""
+"но мы пропустили строку `i=5;`. Поскольку мы не инициализировали `i`, она "
+"содержала любое число, которое оказалось в той области памяти при запуске "
+"программы, и в данном случае это оказалось `4231`."
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1104
+msgid ""
+"The `gdb` command displays the stack frame every time we go into or out of a "
+"function, even if we are using `up` and `down` to move around the call "
+"stack. This shows the name of the function and the values of its arguments, "
+"which helps us keep track of where we are and what is going on. (The stack "
+"is a storage area where the program stores information about the arguments "
+"passed to functions and where to go when it returns from a function call.)"
+msgstr ""
+"Команда `gdb` отображает стек вызовов каждый раз при входе в функцию или "
+"выходе из неё, даже при использовании `up` и `down` для перемещения по стеку "
+"вызовов. Это показывает имя функции и значения её аргументов, что помогает "
+"отслеживать текущее положение и происходящее. (Стек — это область хранения, "
+"где программа сохраняет информацию об аргументах, переданных в функции, и о "
+"месте, куда нужно вернуться после вызова функции.)"
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1106
+#, no-wrap
+msgid "Examining a Core File with gdb"
+msgstr "Изучение файла core с помощью gdb"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1114
+msgid ""
+"To examine a core file, start up `gdb` in the usual way. Instead of typing "
+"`break` or `run`, type"
+msgstr ""
+"Для анализа файла core запустите `gdb` обычным способом. Вместо ввода команд "
+"`break` или `run` введите"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1118
+#, no-wrap
+msgid "(gdb) core progname.core\n"
+msgstr "(gdb) core progname.core\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1121
+msgid ""
+"If the core file is not in the current directory, type `dir /path/to/core/"
+"file` first."
+msgstr ""
+"Если файл core отсутствует в текущем каталоге, сначала введите `dir /путь/к/"
+"core/файлу`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1123
+msgid "The debugger should display something like this:"
+msgstr "Отладчик должен отобразить что-то вроде этого:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1137
+#, no-wrap
+msgid ""
+"% gdb [.filename]#progname#\n"
+"GDB is free software and you are welcome to distribute copies of it\n"
+" under certain conditions; type \"show copying\" to see the conditions.\n"
+"There is absolutely no warranty for GDB; type \"show warranty\" for details.\n"
+"GDB 4.13 (i386-unknown-freebsd), Copyright 1994 Free Software Foundation, Inc.\n"
+"(gdb) core [.filename]#progname.core#\n"
+"Core was generated by `[.filename]#progname#'.\n"
+"Program terminated with signal 11, Segmentation fault.\n"
+"Cannot access memory at address 0x7020796d.\n"
+"#0 0x164a in bazz (anint=0x5) at temp.c:17\n"
+"(gdb)\n"
+msgstr ""
+"% gdb [.filename]#progname#\n"
+"GDB is free software and you are welcome to distribute copies of it\n"
+" under certain conditions; type \"show copying\" to see the conditions.\n"
+"There is absolutely no warranty for GDB; type \"show warranty\" for details.\n"
+"GDB 4.13 (i386-unknown-freebsd), Copyright 1994 Free Software Foundation, Inc.\n"
+"(gdb) core [.filename]#progname.core#\n"
+"Core was generated by `[.filename]#progname#'.\n"
+"Program terminated with signal 11, Segmentation fault.\n"
+"Cannot access memory at address 0x7020796d.\n"
+"#0 0x164a in bazz (anint=0x5) at temp.c:17\n"
+"(gdb)\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1141
+msgid ""
+"In this case, the program was called [.filename]#progname#, so the core file "
+"is called [.filename]#progname.core#. We can see that the program crashed "
+"due to trying to access an area in memory that was not available to it in a "
+"function called `bazz`."
+msgstr ""
+"В этом случае программа называлась [.filename]#progname#, поэтому файл дампа "
+"памяти называется [.filename]#progname.core#. Мы видим, что программа "
+"завершилась аварийно из-за попытки доступа к области памяти, которая ей не "
+"доступна, в функции `bazz`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1145
+msgid ""
+"Sometimes it is useful to be able to see how a function was called, as the "
+"problem could have occurred a long way up the call stack in a complex "
+"program. `bt` causes `gdb` to print out a back-trace of the call stack:"
+msgstr ""
+"Иногда полезно увидеть, как была вызвана функция, поскольку проблема могла "
+"возникнуть гораздо выше по стеку вызовов в сложной программе. `bt` "
+"заставляет `gdb` вывести трассировку стека вызовов:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1153
+#, no-wrap
+msgid ""
+"(gdb) bt\n"
+"#0 0x164a in bazz (anint=0x5) at temp.c:17\n"
+"#1 0xefbfd888 in end ()\n"
+"#2 0x162c in main () at temp.c:11\n"
+"(gdb)\n"
+msgstr ""
+"(gdb) bt\n"
+"#0 0x164a in bazz (anint=0x5) at temp.c:17\n"
+"#1 0xefbfd888 in end ()\n"
+"#2 0x162c in main () at temp.c:11\n"
+"(gdb)\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1157
+msgid ""
+"The `end()` function is called when a program crashes; in this case, the "
+"`bazz()` function was called from `main()`."
+msgstr ""
+"Функция `end()` вызывается при аварийном завершении программы; в данном "
+"случае функция `bazz()` была вызвана из `main()`."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1158
+#, no-wrap
+msgid "Attaching to a Running Program with gdb"
+msgstr "Подключение к работающей программе с помощью gdb"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1163
+msgid ""
+"One of the neatest features about `gdb` is that it can attach to a program "
+"that is already running. Of course, that requires sufficient permissions to "
+"do so. A common problem is stepping through a program that forks and "
+"wanting to trace the child, but the debugger will only trace the parent."
+msgstr ""
+"Одной из самых удобных функций `gdb` является возможность подключения к уже "
+"запущенной программе. Конечно, для этого требуются соответствующие "
+"разрешения. Частой проблемой является пошаговое выполнение программы, "
+"которая создает дочерний процесс, когда нужно отслеживать дочерний процесс, "
+"но отладчик продолжает отслеживать только родительский."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1165
+msgid ""
+"To do that, start up another `gdb`, use `ps` to find the process ID for the "
+"child, and do"
+msgstr ""
+"Для этого запустите другой `gdb`, используйте `ps` для поиска идентификатора "
+"процесса дочернего элемента и выполните"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1169
+#, no-wrap
+msgid "(gdb) attach pid\n"
+msgstr "(gdb) attach pid\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1172
+msgid "in `gdb`, and then debug as usual."
+msgstr "в `gdb`, а затем отлаживайте как обычно."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1191
+msgid ""
+"Now all that is needed is to attach to the child, set PauseMode to `0`, and "
+"wait for the `sleep()` call to return!"
+msgstr ""
+"Теперь осталось только подключиться к дочернему процессу, установить "
+"PauseMode в `0` и дождаться возврата из вызова `sleep()`!"
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1193
+#, no-wrap
+msgid "Using Emacs as a Development Environment"
+msgstr "Использование Emacs в качестве среды разработки"
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1195
+#, no-wrap
+msgid "Emacs"
+msgstr "Emacs"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1199
+msgid ""
+"Emacs is a highly customizable editor-indeed, it has been customized to the "
+"point where it is more like an operating system than an editor! Many "
+"developers and sysadmins do in fact spend practically all their time working "
+"inside Emacs, leaving it only to log out."
+msgstr ""
+"Emacs — это высоконастраиваемый редактор — настолько, что его можно скорее "
+"назвать операционной системой, чем редактором! Многие разработчики и "
+"системные администраторы действительно проводят практически всё своё время, "
+"работая внутри Emacs, выходя из него только для завершения сеанса."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1201
+msgid ""
+"It is impossible even to summarize everything Emacs can do here, but here "
+"are some of the features of interest to developers:"
+msgstr ""
+"Невозможно даже кратко описать все, что может делать Emacs, но вот некоторые "
+"особенности, которые могут быть интересны разработчикам:"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1203
+msgid ""
+"Very powerful editor, allowing search-and-replace on both strings and "
+"regular expressions (patterns), jumping to start/end of block expression, "
+"etc, etc."
+msgstr ""
+"Очень мощный редактор, позволяющий выполнять поиск и замену как строк, так и "
+"регулярных выражений (шаблонов), переход к началу/концу блока выражения и "
+"многое другое."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1204
+msgid "Pull-down menus and online help."
+msgstr "Выпадающие меню и встроенная справка."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1205
+msgid "Language-dependent syntax highlighting and indentation."
+msgstr "Подсветка синтаксиса и форматирование отступов в зависимости от языка."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1206
+msgid "Completely customizable."
+msgstr "Полностью настраиваемый."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1207
+msgid "You can compile and debug programs within Emacs."
+msgstr "Вы можете компилировать и отлаживать программы из Emacs."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1208
+msgid ""
+"On a compilation error, you can jump to the offending line of source code."
+msgstr ""
+"При ошибке компиляции можно перейти к проблемной строке исходного кода."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1209
+msgid ""
+"Friendly-ish front-end to the `info` program used for reading GNU hypertext "
+"documentation, including the documentation on Emacs itself."
+msgstr ""
+"Дружелюбный интерфейс для программы `info`, используемой для чтения "
+"гипертекстовой документации GNU, включая документацию по самому Emacs."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1210
+msgid ""
+"Friendly front-end to `gdb`, allowing you to look at the source code as you "
+"step through your program."
+msgstr ""
+"Дружелюбный интерфейс для `gdb`, позволяющий просматривать исходный код во "
+"время пошагового выполнения программы."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1212
+msgid "And doubtless many more that have been overlooked."
+msgstr "И, несомненно, множество других, которые были упущены из виду."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1214
+msgid ""
+"Emacs can be installed on FreeBSD using the package:editors/emacs[] port."
+msgstr ""
+"Emacs можно установить на FreeBSD с помощью пакета package:editors/emacs[]."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1217
+msgid ""
+"Once it is installed, start it up and do `C-h t` to read an Emacs tutorial-"
+"that means hold down kbd:[control], press kbd:[h], let go of kbd:[control], "
+"and then press kbd:[t]. (Alternatively, you can use the mouse to select "
+"[.guimenuitem]#Emacs Tutorial# from the menu:Help[] menu.)"
+msgstr ""
+"После установки запустите его и выполните `C-h t`, чтобы прочитать "
+"руководство по Emacs — это означает, что нужно удерживать kbd:[control], "
+"нажать kbd:[h], отпустить kbd:[control], а затем нажать kbd:[t]. (Также "
+"можно использовать мышь для выбора [.guimenuitem]#Руководство по Emacs# в "
+"меню menu:Help[].)"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1222
+msgid ""
+"Although Emacs does have menus, it is well worth learning the key bindings, "
+"as it is much quicker when you are editing something to press a couple of "
+"keys than to try to find the mouse and then click on the right place. And, "
+"when you are talking to seasoned Emacs users, you will find they often "
+"casually throw around expressions like \"`M-x replace-s RET foo RET bar "
+"RET`\" so it is useful to know what they mean. And in any case, Emacs has "
+"far too many useful functions for them to all fit on the menu bars."
+msgstr ""
+"Хотя в Emacs и есть меню, стоит изучить сочетания клавиш, так как "
+"редактировать что-либо с их помощью гораздо быстрее, чем искать мышку и "
+"кликать в нужное место. Кроме того, общаясь с опытными пользователями Emacs, "
+"вы часто услышите выражения вроде «`M-x replace-s RET foo RET bar RET`» — "
+"полезно понимать, что они значат. Да и вообще, в Emacs столько полезных "
+"функций, что все они просто не поместятся на панелях меню."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1226
+msgid ""
+"Fortunately, it is quite easy to pick up the key-bindings, as they are "
+"displayed next to the menu item. My advice is to use the menu item for, "
+"say, opening a file until you understand how it works and feel confident "
+"with it, then try doing C-x C-f. When you are happy with that, move on to "
+"another menu command."
+msgstr ""
+"К счастью, освоить сочетания клавиш довольно легко, так как они отображаются "
+"рядом с пунктами меню. Мой совет — использовать пункты меню для, скажем, "
+"открытия файла, пока вы не разберётесь, как это работает, и не почувствуете "
+"себя уверенно, а затем попробуйте выполнить `C-x C-f`. Когда освоитесь с "
+"этим, переходите к следующей команде меню."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1229
+msgid ""
+"If you cannot remember what a particular combination of keys does, select "
+"[.guimenuitem]#Describe Key# from the menu:Help[] menu and type it in-Emacs "
+"will tell you what it does. You can also use the [.guimenuitem]#Command "
+"Apropos# menu item to find out all the commands which contain a particular "
+"word in them, with the key binding next to it."
+msgstr ""
+"Если вы не можете вспомнить, что делает определённая комбинация клавиш, "
+"выберите [.guimenuitem]#Описание Клавиши# в меню menu:Help[] и введите её — "
+"Emacs сообщит, что она делает. Вы также можете использовать пункт меню "
+"[.guimenuitem]#Command Apropos#, чтобы найти все команды, содержащие "
+"определённое слово, с указанием соответствующих клавишных сочетаний."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1232
+msgid ""
+"By the way, the expression above means hold down the kbd:[Meta] key, press "
+"kbd:[x], release the kbd:[Meta] key, type `replace-s` (short for `replace-"
+"string`-another feature of Emacs is that you can abbreviate commands), press "
+"the kbd:[return] key, type `foo` (the string you want replaced), press the "
+"kbd:[return] key, type bar (the string you want to replace `foo` with) and "
+"press kbd:[return] again. Emacs will then do the search-and-replace "
+"operation you have just requested."
+msgstr ""
+"Между прочим, выражение выше означает: удерживайте клавишу kbd:[Meta], "
+"нажмите kbd:[x], отпустите клавишу kbd:[Meta], введите `replace-s` "
+"(сокращение от `replace-string` — ещё одна особенность Emacs в том, что "
+"команды можно сокращать), нажмите клавишу kbd:[return], введите `foo` "
+"(строка, которую нужно заменить), нажмите клавишу kbd:[return], введите "
+"`bar` (строка, на которую нужно заменить `foo`) и снова нажмите kbd:"
+"[return]. Emacs выполнит операцию поиска и замены, которую вы только что "
+"запросили."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1235
+msgid ""
+"If you are wondering what on earth kbd:[Meta] is, it is a special key that "
+"many UNIX(R) workstations have. Unfortunately, PC's do not have one, so it "
+"is usually kbd:[alt] (or if you are unlucky, the kbd:[escape] key)."
+msgstr ""
+"Если вам интересно, что такое kbd:[Meta], то это специальная клавиша, "
+"которая есть на многих рабочих станциях UNIX(R). К сожалению, на PC её нет, "
+"поэтому обычно используется kbd:[alt] (или, если вам не повезло, kbd:"
+"[escape])."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1239
+msgid ""
+"Oh, and to get out of Emacs, do `C-x C-c` (that means hold down the kbd:"
+"[control] key, press kbd:[x], press kbd:[c] and release the kbd:[control] "
+"key). If you have any unsaved files open, Emacs will ask you if you want to "
+"save them. (Ignore the bit in the documentation where it says `C-z` is the "
+"usual way to leave Emacs-that leaves Emacs hanging around in the background, "
+"and is only really useful if you are on a system which does not have virtual "
+"terminals)."
+msgstr ""
+"Ах да, чтобы выйти из Emacs, нажмите `C-x C-c` (это значит зажмите клавишу "
+"kbd:[control], нажмите kbd:[x], затем kbd:[c] и отпустите kbd:[control]). "
+"Если у вас есть несохранённые файлы, Emacs спросит, хотите ли вы их "
+"сохранить. (Игнорируйте часть документации, где говорится, что `C-z` — это "
+"обычный способ выхода из Emacs — это оставляет Emacs работающим в фоне и "
+"полезно только на системах без виртуальных терминалов)."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1240
+#, no-wrap
+msgid "Configuring Emacs"
+msgstr "Настройка Emacs"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1243
+msgid ""
+"Emacs does many wonderful things; some of them are built in, some of them "
+"need to be configured."
+msgstr ""
+"Emacs делает много замечательных вещей; некоторые из них встроены, некоторые "
+"требуют настройки."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1247
+msgid ""
+"Instead of using a proprietary macro language for configuration, Emacs uses "
+"a version of Lisp specially adapted for editors, known as Emacs Lisp. "
+"Working with Emacs Lisp can be quite helpful if you want to go on and learn "
+"something like Common Lisp. Emacs Lisp has many features of Common Lisp, "
+"although it is considerably smaller (and thus easier to master)."
+msgstr ""
+"Вместо использования проприетарного языка макросов для конфигурации, Emacs "
+"применяет версию Lisp, специально адаптированную для редакторов, известную "
+"как Emacs Lisp. Работа с Emacs Lisp может быть весьма полезной, если вы "
+"хотите продолжить и изучить что-то вроде Common Lisp. Emacs Lisp обладает "
+"многими возможностями Common Lisp, хотя и значительно меньше (и, "
+"следовательно, проще для освоения)."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1249
+msgid ""
+"The best way to learn Emacs Lisp is to read the online link:https://"
+"www.gnu.org/software/emacs/manual/elisp.html[Emacs Reference] manual."
+msgstr ""
+"Лучший способ изучить Emacs Lisp — это прочитать онлайн-руководство "
+"link:https://www.gnu.org/software/emacs/manual/elisp.html[Emacs Reference]."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1254
+msgid ""
+"However, there is no need to actually know any Lisp to get started with "
+"configuring Emacs, as I have included a sample [.filename]#.emacs#, which "
+"should be enough to get you started. Just copy it into your home directory "
+"and restart Emacs if it is already running; it will read the commands from "
+"the file and (hopefully) give you a useful basic setup."
+msgstr ""
+"Однако для начала настройки Emacs не обязательно знать Lisp, так как я "
+"включил пример файла [.filename]#.emacs#, которого должно быть достаточно "
+"для старта. Просто скопируйте его в свой домашний каталог и перезапустите "
+"Emacs, если он уже запущен; он прочитает команды из файла и (надеюсь) "
+"предоставит вам полезную базовую конфигурацию."
+
+#. type: Block title
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1255
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1273
+#, no-wrap
+msgid "A Sample [.filename]#.emacs#"
+msgstr "Пример файла [.filename]#.emacs#"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1258
+msgid ""
+"Unfortunately, there is far too much here to explain it in detail; however "
+"there are one or two points worth mentioning."
+msgstr ""
+"К сожалению, здесь слишком много информации, чтобы объяснять всё подробно; "
+"однако есть один или два момента, которые стоит упомянуть."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1260
+msgid "Everything beginning with a `;` is a comment and is ignored by Emacs."
+msgstr "Всё, что начинается с `;`, является комментарием и игнорируется Emacs."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1261
+msgid ""
+"In the first line, the `-*- Emacs-Lisp -*-` is so that we can edit "
+"[.filename]#.emacs# itself within Emacs and get all the fancy features for "
+"editing Emacs Lisp. Emacs usually tries to guess this based on the filename, "
+"and may not get it right for [.filename]#.emacs#."
+msgstr ""
+"В первой строке `-*- Emacs-Lisp -*-` нужен для того, чтобы мы могли "
+"редактировать сам файл [.filename]#.emacs# в Emacs и использовать все "
+"удобные функции для редактирования Emacs Lisp. Обычно Emacs пытается угадать "
+"это по имени файла, но может не сделать это правильно для "
+"[.filename]#.emacs#."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1262
+msgid ""
+"The kbd:[tab] key is bound to an indentation function in some modes, so when "
+"you press the tab key, it will indent the current line of code. If you want "
+"to put a tab character in whatever you are writing, hold the kbd:[control] "
+"key down while you are pressing the kbd:[tab] key."
+msgstr ""
+"Клавиша kbd:[tab] связана с функцией отступа в некоторых режимах, поэтому "
+"при нажатии клавиши tab текущая строка кода будет с отступом. Если вы хотите "
+"вставить символ табуляции в текст, удерживайте клавишу kbd:[control] во "
+"время нажатия kbd:[tab]."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1263
+msgid ""
+"This file supports syntax highlighting for C, C++, Perl, Lisp and Scheme, by "
+"guessing the language from the filename."
+msgstr ""
+"Этот файл поддерживает подсветку синтаксиса для C, C++, Perl, Lisp и Scheme, "
+"определяя язык по имени файла."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1264
+msgid ""
+"Emacs already has a pre-defined function called `next-error`. In a "
+"compilation output window, this allows you to move from one compilation "
+"error to the next by doing `M-n`; we define a complementary function, "
+"`previous-error`, that allows you to go to a previous error by doing `M-p`. "
+"The nicest feature of all is that `C-c C-c` will open up the source file in "
+"which the error occurred and jump to the appropriate line."
+msgstr ""
+"В Emacs уже есть предопределённая функция `next-error`. В окне вывода "
+"компиляции это позволяет переходить от одной ошибки компиляции к следующей с "
+"помощью `M-n`; мы определяем дополнительную функцию `previous-error`, "
+"которая позволяет вернуться к предыдущей ошибке с помощью `M-p`. Самое "
+"приятное — сочетание `C-c C-c` откроет исходный файл, в котором произошла "
+"ошибка, и перейдёт на соответствующую строку."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1265
+msgid ""
+"We enable Emacs's ability to act as a server, so that if you are doing "
+"something outside Emacs and you want to edit a file, you can just type in"
+msgstr ""
+"Включаем возможность Emacs работать как сервер, так что если вы заняты чем-"
+"то вне Emacs и хотите отредактировать файл, можно просто ввести"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1269
+#, no-wrap
+msgid "% emacsclient filename\n"
+msgstr "% emacsclient filename\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1272
+msgid ""
+"and then you can edit the file in your Emacs!footnote:[Many Emacs users set "
+"their EDITOR environment to emacsclient so this happens every time they need "
+"to edit a file.]"
+msgstr ""
+"и затем вы можете редактировать файл в вашем Emacs!footnote:[Многие "
+"пользователи Emacs устанавливают переменную окружения EDITOR в emacsclient, "
+"так что это происходит каждый раз, когда им нужно отредактировать файл.]"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1278
+#, no-wrap
+msgid ";; -*-Emacs-Lisp-*-\n"
+msgstr ";; -*-Emacs-Lisp-*-\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1283
+#, no-wrap
+msgid ""
+";; This file is designed to be re-evaled; use the variable first-time\n"
+";; to avoid any problems with this.\n"
+"(defvar first-time t\n"
+" \"Flag signifying this is the first time that .emacs has been evaled\")\n"
+msgstr ""
+";; This file is designed to be re-evaled; use the variable first-time\n"
+";; to avoid any problems with this.\n"
+"(defvar first-time t\n"
+" \"Flag signifying this is the first time that .emacs has been evaled\")\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1291
+#, no-wrap
+msgid ""
+";; Meta\n"
+"(global-set-key \"\\M- \" 'set-mark-command)\n"
+"(global-set-key \"\\M-\\C-h\" 'backward-kill-word)\n"
+"(global-set-key \"\\M-\\C-r\" 'query-replace)\n"
+"(global-set-key \"\\M-r\" 'replace-string)\n"
+"(global-set-key \"\\M-g\" 'goto-line)\n"
+"(global-set-key \"\\M-h\" 'help-command)\n"
+msgstr ""
+";; Meta\n"
+"(global-set-key \"\\M- \" 'set-mark-command)\n"
+"(global-set-key \"\\M-\\C-h\" 'backward-kill-word)\n"
+"(global-set-key \"\\M-\\C-r\" 'query-replace)\n"
+"(global-set-key \"\\M-r\" 'replace-string)\n"
+"(global-set-key \"\\M-g\" 'goto-line)\n"
+"(global-set-key \"\\M-h\" 'help-command)\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1312
+#, no-wrap
+msgid ""
+";; Function keys\n"
+"(global-set-key [f1] 'manual-entry)\n"
+"(global-set-key [f2] 'info)\n"
+"(global-set-key [f3] 'repeat-complex-command)\n"
+"(global-set-key [f4] 'advertised-undo)\n"
+"(global-set-key [f5] 'eval-current-buffer)\n"
+"(global-set-key [f6] 'buffer-menu)\n"
+"(global-set-key [f7] 'other-window)\n"
+"(global-set-key [f8] 'find-file)\n"
+"(global-set-key [f9] 'save-buffer)\n"
+"(global-set-key [f10] 'next-error)\n"
+"(global-set-key [f11] 'compile)\n"
+"(global-set-key [f12] 'grep)\n"
+"(global-set-key [C-f1] 'compile)\n"
+"(global-set-key [C-f2] 'grep)\n"
+"(global-set-key [C-f3] 'next-error)\n"
+"(global-set-key [C-f4] 'previous-error)\n"
+"(global-set-key [C-f5] 'display-faces)\n"
+"(global-set-key [C-f8] 'dired)\n"
+"(global-set-key [C-f10] 'kill-compilation)\n"
+msgstr ""
+";; Function keys\n"
+"(global-set-key [f1] 'manual-entry)\n"
+"(global-set-key [f2] 'info)\n"
+"(global-set-key [f3] 'repeat-complex-command)\n"
+"(global-set-key [f4] 'advertised-undo)\n"
+"(global-set-key [f5] 'eval-current-buffer)\n"
+"(global-set-key [f6] 'buffer-menu)\n"
+"(global-set-key [f7] 'other-window)\n"
+"(global-set-key [f8] 'find-file)\n"
+"(global-set-key [f9] 'save-buffer)\n"
+"(global-set-key [f10] 'next-error)\n"
+"(global-set-key [f11] 'compile)\n"
+"(global-set-key [f12] 'grep)\n"
+"(global-set-key [C-f1] 'compile)\n"
+"(global-set-key [C-f2] 'grep)\n"
+"(global-set-key [C-f3] 'next-error)\n"
+"(global-set-key [C-f4] 'previous-error)\n"
+"(global-set-key [C-f5] 'display-faces)\n"
+"(global-set-key [C-f8] 'dired)\n"
+"(global-set-key [C-f10] 'kill-compilation)\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1330
+#, no-wrap
+msgid ""
+";; Keypad bindings\n"
+"(global-set-key [up] \"\\C-p\")\n"
+"(global-set-key [down] \"\\C-n\")\n"
+"(global-set-key [left] \"\\C-b\")\n"
+"(global-set-key [right] \"\\C-f\")\n"
+"(global-set-key [home] \"\\C-a\")\n"
+"(global-set-key [end] \"\\C-e\")\n"
+"(global-set-key [prior] \"\\M-v\")\n"
+"(global-set-key [next] \"\\C-v\")\n"
+"(global-set-key [C-up] \"\\M-\\C-b\")\n"
+"(global-set-key [C-down] \"\\M-\\C-f\")\n"
+"(global-set-key [C-left] \"\\M-b\")\n"
+"(global-set-key [C-right] \"\\M-f\")\n"
+"(global-set-key [C-home] \"\\M-<\")\n"
+"(global-set-key [C-end] \"\\M->\")\n"
+"(global-set-key [C-prior] \"\\M-<\")\n"
+"(global-set-key [C-next] \"\\M->\")\n"
+msgstr ""
+";; Keypad bindings\n"
+"(global-set-key [up] \"\\C-p\")\n"
+"(global-set-key [down] \"\\C-n\")\n"
+"(global-set-key [left] \"\\C-b\")\n"
+"(global-set-key [right] \"\\C-f\")\n"
+"(global-set-key [home] \"\\C-a\")\n"
+"(global-set-key [end] \"\\C-e\")\n"
+"(global-set-key [prior] \"\\M-v\")\n"
+"(global-set-key [next] \"\\C-v\")\n"
+"(global-set-key [C-up] \"\\M-\\C-b\")\n"
+"(global-set-key [C-down] \"\\M-\\C-f\")\n"
+"(global-set-key [C-left] \"\\M-b\")\n"
+"(global-set-key [C-right] \"\\M-f\")\n"
+"(global-set-key [C-home] \"\\M-<\")\n"
+"(global-set-key [C-end] \"\\M->\")\n"
+"(global-set-key [C-prior] \"\\M-<\")\n"
+"(global-set-key [C-next] \"\\M->\")\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1333
+#, no-wrap
+msgid ""
+";; Mouse\n"
+"(global-set-key [mouse-3] 'imenu)\n"
+msgstr ""
+";; Mouse\n"
+"(global-set-key [mouse-3] 'imenu)\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1337
+#, no-wrap
+msgid ""
+";; Misc\n"
+"(global-set-key [C-tab] \"\\C-q\\t\")\t; Control tab quotes a tab.\n"
+"(setq backup-by-copying-when-mismatch t)\n"
+msgstr ""
+";; Misc\n"
+"(global-set-key [C-tab] \"\\C-q\\t\")\t; Control tab quotes a tab.\n"
+"(setq backup-by-copying-when-mismatch t)\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1342
+#, no-wrap
+msgid ""
+";; Treat 'y' or <CR> as yes, 'n' as no.\n"
+"(fset 'yes-or-no-p 'y-or-n-p)\n"
+"(define-key query-replace-map [return] 'act)\n"
+"(define-key query-replace-map [?\\C-m] 'act)\n"
+msgstr ""
+";; Treat 'y' or <CR> as yes, 'n' as no.\n"
+"(fset 'yes-or-no-p 'y-or-n-p)\n"
+"(define-key query-replace-map [return] 'act)\n"
+"(define-key query-replace-map [?\\C-m] 'act)\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1346
+#, no-wrap
+msgid ""
+";; Load packages\n"
+"(require 'desktop)\n"
+"(require 'tar-mode)\n"
+msgstr ""
+";; Load packages\n"
+"(require 'desktop)\n"
+"(require 'tar-mode)\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1352
+#, no-wrap
+msgid ""
+";; Pretty diff mode\n"
+"(autoload 'ediff-buffers \"ediff\" \"Intelligent Emacs interface to diff\" t)\n"
+"(autoload 'ediff-files \"ediff\" \"Intelligent Emacs interface to diff\" t)\n"
+"(autoload 'ediff-files-remote \"ediff\"\n"
+" \"Intelligent Emacs interface to diff\")\n"
+msgstr ""
+";; Pretty diff mode\n"
+"(autoload 'ediff-buffers \"ediff\" \"Intelligent Emacs interface to diff\" t)\n"
+"(autoload 'ediff-files \"ediff\" \"Intelligent Emacs interface to diff\" t)\n"
+"(autoload 'ediff-files-remote \"ediff\"\n"
+" \"Intelligent Emacs interface to diff\")\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1361
+#, no-wrap
+msgid ""
+"(if first-time\n"
+" (setq auto-mode-alist\n"
+"\t (append '((\"\\\\.cpp$\" . c++-mode)\n"
+"\t\t (\"\\\\.hpp$\" . c++-mode)\n"
+"\t\t (\"\\\\.lsp$\" . lisp-mode)\n"
+"\t\t (\"\\\\.scm$\" . scheme-mode)\n"
+"\t\t (\"\\\\.pl$\" . perl-mode)\n"
+"\t\t ) auto-mode-alist)))\n"
+msgstr ""
+"(if first-time\n"
+" (setq auto-mode-alist\n"
+"\t (append '((\"\\\\.cpp$\" . c++-mode)\n"
+"\t\t (\"\\\\.hpp$\" . c++-mode)\n"
+"\t\t (\"\\\\.lsp$\" . lisp-mode)\n"
+"\t\t (\"\\\\.scm$\" . scheme-mode)\n"
+"\t\t (\"\\\\.pl$\" . perl-mode)\n"
+"\t\t ) auto-mode-alist)))\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1366
+#, no-wrap
+msgid ""
+";; Auto font lock mode\n"
+"(defvar font-lock-auto-mode-list\n"
+" (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'lisp-mode 'perl-mode 'scheme-mode)\n"
+" \"List of modes to always start in font-lock-mode\")\n"
+msgstr ""
+";; Auto font lock mode\n"
+"(defvar font-lock-auto-mode-list\n"
+" (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'lisp-mode 'perl-mode 'scheme-mode)\n"
+" \"List of modes to always start in font-lock-mode\")\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1371
+#, no-wrap
+msgid ""
+"(defvar font-lock-mode-keyword-alist\n"
+" '((c++-c-mode . c-font-lock-keywords)\n"
+" (perl-mode . perl-font-lock-keywords))\n"
+" \"Associations between modes and keywords\")\n"
+msgstr ""
+"(defvar font-lock-mode-keyword-alist\n"
+" '((c++-c-mode . c-font-lock-keywords)\n"
+" (perl-mode . perl-font-lock-keywords))\n"
+" \"Associations between modes and keywords\")\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1379
+#, no-wrap
+msgid ""
+"(defun font-lock-auto-mode-select ()\n"
+" \"Automatically select font-lock-mode if the current major mode is in font-lock-auto-mode-list\"\n"
+" (if (memq major-mode font-lock-auto-mode-list)\n"
+" (progn\n"
+"\t(font-lock-mode t))\n"
+" )\n"
+" )\n"
+msgstr ""
+"(defun font-lock-auto-mode-select ()\n"
+" \"Automatically select font-lock-mode if the current major mode is in font-lock-auto-mode-list\"\n"
+" (if (memq major-mode font-lock-auto-mode-list)\n"
+" (progn\n"
+"\t(font-lock-mode t))\n"
+" )\n"
+" )\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1381
+#, no-wrap
+msgid "(global-set-key [M-f1] 'font-lock-fontify-buffer)\n"
+msgstr "(global-set-key [M-f1] 'font-lock-fontify-buffer)\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1398
+#, no-wrap
+msgid ""
+";; New dabbrev stuff\n"
+";(require 'new-dabbrev)\n"
+"(setq dabbrev-always-check-other-buffers t)\n"
+"(setq dabbrev-abbrev-char-regexp \"\\\\sw\\\\|\\\\s_\")\n"
+"(add-hook 'emacs-lisp-mode-hook\n"
+"\t '(lambda ()\n"
+"\t (set (make-local-variable 'dabbrev-case-fold-search) nil)\n"
+"\t (set (make-local-variable 'dabbrev-case-replace) nil)))\n"
+"(add-hook 'c-mode-hook\n"
+"\t '(lambda ()\n"
+"\t (set (make-local-variable 'dabbrev-case-fold-search) nil)\n"
+"\t (set (make-local-variable 'dabbrev-case-replace) nil)))\n"
+"(add-hook 'text-mode-hook\n"
+"\t '(lambda ()\n"
+"\t (set (make-local-variable 'dabbrev-case-fold-search) t)\n"
+"\t (set (make-local-variable 'dabbrev-case-replace) t)))\n"
+msgstr ""
+";; New dabbrev stuff\n"
+";(require 'new-dabbrev)\n"
+"(setq dabbrev-always-check-other-buffers t)\n"
+"(setq dabbrev-abbrev-char-regexp \"\\\\sw\\\\|\\\\s_\")\n"
+"(add-hook 'emacs-lisp-mode-hook\n"
+"\t '(lambda ()\n"
+"\t (set (make-local-variable 'dabbrev-case-fold-search) nil)\n"
+"\t (set (make-local-variable 'dabbrev-case-replace) nil)))\n"
+"(add-hook 'c-mode-hook\n"
+"\t '(lambda ()\n"
+"\t (set (make-local-variable 'dabbrev-case-fold-search) nil)\n"
+"\t (set (make-local-variable 'dabbrev-case-replace) nil)))\n"
+"(add-hook 'text-mode-hook\n"
+"\t '(lambda ()\n"
+"\t (set (make-local-variable 'dabbrev-case-fold-search) t)\n"
+"\t (set (make-local-variable 'dabbrev-case-replace) t)))\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1410
+#, no-wrap
+msgid ""
+";; C++ and C mode...\n"
+"(defun my-c++-mode-hook ()\n"
+" (setq tab-width 4)\n"
+" (define-key c++-mode-map \"\\C-m\" 'reindent-then-newline-and-indent)\n"
+" (define-key c++-mode-map \"\\C-ce\" 'c-comment-edit)\n"
+" (setq c++-auto-hungry-initial-state 'none)\n"
+" (setq c++-delete-function 'backward-delete-char)\n"
+" (setq c++-tab-always-indent t)\n"
+" (setq c-indent-level 4)\n"
+" (setq c-continued-statement-offset 4)\n"
+" (setq c++-empty-arglist-indent 4))\n"
+msgstr ""
+";; C++ and C mode...\n"
+"(defun my-c++-mode-hook ()\n"
+" (setq tab-width 4)\n"
+" (define-key c++-mode-map \"\\C-m\" 'reindent-then-newline-and-indent)\n"
+" (define-key c++-mode-map \"\\C-ce\" 'c-comment-edit)\n"
+" (setq c++-auto-hungry-initial-state 'none)\n"
+" (setq c++-delete-function 'backward-delete-char)\n"
+" (setq c++-tab-always-indent t)\n"
+" (setq c-indent-level 4)\n"
+" (setq c-continued-statement-offset 4)\n"
+" (setq c++-empty-arglist-indent 4))\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1424
+#, no-wrap
+msgid ""
+"(defun my-c-mode-hook ()\n"
+" (setq tab-width 4)\n"
+" (define-key c-mode-map \"\\C-m\" 'reindent-then-newline-and-indent)\n"
+" (define-key c-mode-map \"\\C-ce\" 'c-comment-edit)\n"
+" (setq c-auto-hungry-initial-state 'none)\n"
+" (setq c-delete-function 'backward-delete-char)\n"
+" (setq c-tab-always-indent t)\n"
+";; BSD-ish indentation style\n"
+" (setq c-indent-level 4)\n"
+" (setq c-continued-statement-offset 4)\n"
+" (setq c-brace-offset -4)\n"
+" (setq c-argdecl-indent 0)\n"
+" (setq c-label-offset -4))\n"
+msgstr ""
+"(defun my-c-mode-hook ()\n"
+" (setq tab-width 4)\n"
+" (define-key c-mode-map \"\\C-m\" 'reindent-then-newline-and-indent)\n"
+" (define-key c-mode-map \"\\C-ce\" 'c-comment-edit)\n"
+" (setq c-auto-hungry-initial-state 'none)\n"
+" (setq c-delete-function 'backward-delete-char)\n"
+" (setq c-tab-always-indent t)\n"
+";; BSD-ish indentation style\n"
+" (setq c-indent-level 4)\n"
+" (setq c-continued-statement-offset 4)\n"
+" (setq c-brace-offset -4)\n"
+" (setq c-argdecl-indent 0)\n"
+" (setq c-label-offset -4))\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1431
+#, no-wrap
+msgid ""
+";; Perl mode\n"
+"(defun my-perl-mode-hook ()\n"
+" (setq tab-width 4)\n"
+" (define-key c++-mode-map \"\\C-m\" 'reindent-then-newline-and-indent)\n"
+" (setq perl-indent-level 4)\n"
+" (setq perl-continued-statement-offset 4))\n"
+msgstr ""
+";; Perl mode\n"
+"(defun my-perl-mode-hook ()\n"
+" (setq tab-width 4)\n"
+" (define-key c++-mode-map \"\\C-m\" 'reindent-then-newline-and-indent)\n"
+" (setq perl-indent-level 4)\n"
+" (setq perl-continued-statement-offset 4))\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1435
+#, no-wrap
+msgid ""
+";; Scheme mode...\n"
+"(defun my-scheme-mode-hook ()\n"
+" (define-key scheme-mode-map \"\\C-m\" 'reindent-then-newline-and-indent))\n"
+msgstr ""
+";; Scheme mode...\n"
+"(defun my-scheme-mode-hook ()\n"
+" (define-key scheme-mode-map \"\\C-m\" 'reindent-then-newline-and-indent))\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1441
+#, no-wrap
+msgid ""
+";; Emacs-Lisp mode...\n"
+"(defun my-lisp-mode-hook ()\n"
+" (define-key lisp-mode-map \"\\C-m\" 'reindent-then-newline-and-indent)\n"
+" (define-key lisp-mode-map \"\\C-i\" 'lisp-indent-line)\n"
+" (define-key lisp-mode-map \"\\C-j\" 'eval-print-last-sexp))\n"
+msgstr ""
+";; Emacs-Lisp mode...\n"
+"(defun my-lisp-mode-hook ()\n"
+" (define-key lisp-mode-map \"\\C-m\" 'reindent-then-newline-and-indent)\n"
+" (define-key lisp-mode-map \"\\C-i\" 'lisp-indent-line)\n"
+" (define-key lisp-mode-map \"\\C-j\" 'eval-print-last-sexp))\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1449
+#, no-wrap
+msgid ""
+";; Add all of the hooks...\n"
+"(add-hook 'c++-mode-hook 'my-c++-mode-hook)\n"
+"(add-hook 'c-mode-hook 'my-c-mode-hook)\n"
+"(add-hook 'scheme-mode-hook 'my-scheme-mode-hook)\n"
+"(add-hook 'emacs-lisp-mode-hook 'my-lisp-mode-hook)\n"
+"(add-hook 'lisp-mode-hook 'my-lisp-mode-hook)\n"
+"(add-hook 'perl-mode-hook 'my-perl-mode-hook)\n"
+msgstr ""
+";; Add all of the hooks...\n"
+"(add-hook 'c++-mode-hook 'my-c++-mode-hook)\n"
+"(add-hook 'c-mode-hook 'my-c-mode-hook)\n"
+"(add-hook 'scheme-mode-hook 'my-scheme-mode-hook)\n"
+"(add-hook 'emacs-lisp-mode-hook 'my-lisp-mode-hook)\n"
+"(add-hook 'lisp-mode-hook 'my-lisp-mode-hook)\n"
+"(add-hook 'perl-mode-hook 'my-perl-mode-hook)\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1455
+#, no-wrap
+msgid ""
+";; Complement to next-error\n"
+"(defun previous-error (n)\n"
+" \"Visit previous compilation error message and corresponding source code.\"\n"
+" (interactive \"p\")\n"
+" (next-error (- n)))\n"
+msgstr ""
+";; Complement to next-error\n"
+"(defun previous-error (n)\n"
+" \"Visit previous compilation error message and corresponding source code.\"\n"
+" (interactive \"p\")\n"
+" (next-error (- n)))\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1468
+#, no-wrap
+msgid ""
+";; Misc...\n"
+"(transient-mark-mode 1)\n"
+"(setq mark-even-if-inactive t)\n"
+"(setq visible-bell nil)\n"
+"(setq next-line-add-newlines nil)\n"
+"(setq compile-command \"make\")\n"
+"(setq suggest-key-bindings nil)\n"
+"(put 'eval-expression 'disabled nil)\n"
+"(put 'narrow-to-region 'disabled nil)\n"
+"(put 'set-goal-column 'disabled nil)\n"
+"(if (>= emacs-major-version 21)\n"
+"\t(setq show-trailing-whitespace t))\n"
+msgstr ""
+";; Misc...\n"
+"(transient-mark-mode 1)\n"
+"(setq mark-even-if-inactive t)\n"
+"(setq visible-bell nil)\n"
+"(setq next-line-add-newlines nil)\n"
+"(setq compile-command \"make\")\n"
+"(setq suggest-key-bindings nil)\n"
+"(put 'eval-expression 'disabled nil)\n"
+"(put 'narrow-to-region 'disabled nil)\n"
+"(put 'set-goal-column 'disabled nil)\n"
+"(if (>= emacs-major-version 21)\n"
+"\t(setq show-trailing-whitespace t))\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1474
+#, no-wrap
+msgid ""
+";; Elisp archive searching\n"
+"(autoload 'format-lisp-code-directory \"lispdir\" nil t)\n"
+"(autoload 'lisp-dir-apropos \"lispdir\" nil t)\n"
+"(autoload 'lisp-dir-retrieve \"lispdir\" nil t)\n"
+"(autoload 'lisp-dir-verify \"lispdir\" nil t)\n"
+msgstr ""
+";; Elisp archive searching\n"
+"(autoload 'format-lisp-code-directory \"lispdir\" nil t)\n"
+"(autoload 'lisp-dir-apropos \"lispdir\" nil t)\n"
+"(autoload 'lisp-dir-retrieve \"lispdir\" nil t)\n"
+"(autoload 'lisp-dir-verify \"lispdir\" nil t)\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1483
+#, no-wrap
+msgid ""
+";; Font lock mode\n"
+"(defun my-make-face (face color &optional bold)\n"
+" \"Create a face from a color and optionally make it bold\"\n"
+" (make-face face)\n"
+" (copy-face 'default face)\n"
+" (set-face-foreground face color)\n"
+" (if bold (make-face-bold face))\n"
+" )\n"
+msgstr ""
+";; Font lock mode\n"
+"(defun my-make-face (face color &optional bold)\n"
+" \"Create a face from a color and optionally make it bold\"\n"
+" (make-face face)\n"
+" (copy-face 'default face)\n"
+" (set-face-foreground face color)\n"
+" (if bold (make-face-bold face))\n"
+" )\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1496
+#, no-wrap
+msgid ""
+"(if (eq window-system 'x)\n"
+" (progn\n"
+" (my-make-face 'blue \"blue\")\n"
+" (my-make-face 'red \"red\")\n"
+" (my-make-face 'green \"dark green\")\n"
+" (setq font-lock-comment-face 'blue)\n"
+" (setq font-lock-string-face 'bold)\n"
+" (setq font-lock-type-face 'bold)\n"
+" (setq font-lock-keyword-face 'bold)\n"
+" (setq font-lock-function-name-face 'red)\n"
+" (setq font-lock-doc-string-face 'green)\n"
+" (add-hook 'find-file-hooks 'font-lock-auto-mode-select)\n"
+msgstr ""
+"(if (eq window-system 'x)\n"
+" (progn\n"
+" (my-make-face 'blue \"blue\")\n"
+" (my-make-face 'red \"red\")\n"
+" (my-make-face 'green \"dark green\")\n"
+" (setq font-lock-comment-face 'blue)\n"
+" (setq font-lock-string-face 'bold)\n"
+" (setq font-lock-type-face 'bold)\n"
+" (setq font-lock-keyword-face 'bold)\n"
+" (setq font-lock-function-name-face 'red)\n"
+" (setq font-lock-doc-string-face 'green)\n"
+" (add-hook 'find-file-hooks 'font-lock-auto-mode-select)\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1504
+#, no-wrap
+msgid ""
+" (setq baud-rate 1000000)\n"
+" (global-set-key \"\\C-cmm\" 'menu-bar-mode)\n"
+" (global-set-key \"\\C-cms\" 'scroll-bar-mode)\n"
+" (global-set-key [backspace] 'backward-delete-char)\n"
+"\t\t\t\t\t; (global-set-key [delete] 'delete-char)\n"
+" (standard-display-european t)\n"
+" (load-library \"iso-transl\")))\n"
+msgstr ""
+" (setq baud-rate 1000000)\n"
+" (global-set-key \"\\C-cmm\" 'menu-bar-mode)\n"
+" (global-set-key \"\\C-cms\" 'scroll-bar-mode)\n"
+" (global-set-key [backspace] 'backward-delete-char)\n"
+"\t\t\t\t\t; (global-set-key [delete] 'delete-char)\n"
+" (standard-display-european t)\n"
+" (load-library \"iso-transl\")))\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1521
+#, no-wrap
+msgid ""
+";; X11 or PC using direct screen writes\n"
+"(if window-system\n"
+" (progn\n"
+" ;; (global-set-key [M-f1] 'hilit-repaint-command)\n"
+" ;; (global-set-key [M-f2] [?\\C-u M-f1])\n"
+" (setq hilit-mode-enable-list\n"
+"\t '(not text-mode c-mode c++-mode emacs-lisp-mode lisp-mode\n"
+"\t\t scheme-mode)\n"
+"\t hilit-auto-highlight nil\n"
+"\t hilit-auto-rehighlight 'visible\n"
+"\t hilit-inhibit-hooks nil\n"
+"\t hilit-inhibit-rebinding t)\n"
+" (require 'hilit19)\n"
+" (require 'paren))\n"
+" (setq baud-rate 2400)\t\t\t; For slow serial connections\n"
+" )\n"
+msgstr ""
+";; X11 or PC using direct screen writes\n"
+"(if window-system\n"
+" (progn\n"
+" ;; (global-set-key [M-f1] 'hilit-repaint-command)\n"
+" ;; (global-set-key [M-f2] [?\\C-u M-f1])\n"
+" (setq hilit-mode-enable-list\n"
+"\t '(not text-mode c-mode c++-mode emacs-lisp-mode lisp-mode\n"
+"\t\t scheme-mode)\n"
+"\t hilit-auto-highlight nil\n"
+"\t hilit-auto-rehighlight 'visible\n"
+"\t hilit-inhibit-hooks nil\n"
+"\t hilit-inhibit-rebinding t)\n"
+" (require 'hilit19)\n"
+" (require 'paren))\n"
+" (setq baud-rate 2400)\t\t\t; For slow serial connections\n"
+" )\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1530
+#, no-wrap
+msgid ""
+";; TTY type terminal\n"
+"(if (and (not window-system)\n"
+"\t (not (equal system-type 'ms-dos)))\n"
+" (progn\n"
+" (if first-time\n"
+"\t (progn\n"
+"\t (keyboard-translate ?\\C-h ?\\C-?)\n"
+"\t (keyboard-translate ?\\C-? ?\\C-h)))))\n"
+msgstr ""
+";; TTY type terminal\n"
+"(if (and (not window-system)\n"
+"\t (not (equal system-type 'ms-dos)))\n"
+" (progn\n"
+" (if first-time\n"
+"\t (progn\n"
+"\t (keyboard-translate ?\\C-h ?\\C-?)\n"
+"\t (keyboard-translate ?\\C-? ?\\C-h)))))\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1536
+#, no-wrap
+msgid ""
+";; Under UNIX\n"
+"(if (not (equal system-type 'ms-dos))\n"
+" (progn\n"
+" (if first-time\n"
+"\t (server-start))))\n"
+msgstr ""
+";; Under UNIX\n"
+"(if (not (equal system-type 'ms-dos))\n"
+" (progn\n"
+" (if first-time\n"
+"\t (server-start))))\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1544
+#, no-wrap
+msgid ""
+";; Add any face changes here\n"
+"(add-hook 'term-setup-hook 'my-term-setup-hook)\n"
+"(defun my-term-setup-hook ()\n"
+" (if (eq window-system 'pc)\n"
+" (progn\n"
+";;\t(set-face-background 'default \"red\")\n"
+"\t)))\n"
+msgstr ""
+";; Add any face changes here\n"
+"(add-hook 'term-setup-hook 'my-term-setup-hook)\n"
+"(defun my-term-setup-hook ()\n"
+" (if (eq window-system 'pc)\n"
+" (progn\n"
+";;\t(set-face-background 'default \"red\")\n"
+"\t)))\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1550
+#, no-wrap
+msgid ""
+";; Restore the \"desktop\" - do this as late as possible\n"
+"(if first-time\n"
+" (progn\n"
+" (desktop-load-default)\n"
+" (desktop-read)))\n"
+msgstr ""
+";; Restore the \"desktop\" - do this as late as possible\n"
+"(if first-time\n"
+" (progn\n"
+" (desktop-load-default)\n"
+" (desktop-read)))\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1553
+#, no-wrap
+msgid ""
+";; Indicate that this file has been read at least once\n"
+"(setq first-time nil)\n"
+msgstr ""
+";; Indicate that this file has been read at least once\n"
+"(setq first-time nil)\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1555
+#, no-wrap
+msgid ";; No need to debug anything now\n"
+msgstr ";; No need to debug anything now\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1557
+#, no-wrap
+msgid "(setq debug-on-error nil)\n"
+msgstr "(setq debug-on-error nil)\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1560
+#, no-wrap
+msgid ""
+";; All done\n"
+"(message \"All done, %s%s\" (user-login-name) \".\")\n"
+msgstr ""
+";; All done\n"
+"(message \"All done, %s%s\" (user-login-name) \".\")\n"
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1563
+#, no-wrap
+msgid "Extending the Range of Languages Emacs Understands"
+msgstr "Расширение списка языков, понимаемых Emacs"
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1566
+msgid ""
+"Now, this is all very well if you only want to program in the languages "
+"already catered for in [.filename]#.emacs# (C, C++, Perl, Lisp and Scheme), "
+"but what happens if a new language called \"whizbang\" comes out, full of "
+"exciting features?"
+msgstr ""
+"Вот, это все хорошо, если вы хотите программировать только на языках, уже "
+"предусмотренных в [.filename]#.emacs# (C, C++, Perl, Lisp и Scheme), но что "
+"произойдет, если появится новый язык под названием \"whizbang\", полный "
+"захватывающих возможностей?"
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1570
+msgid ""
+"The first thing to do is find out if whizbang comes with any files that tell "
+"Emacs about the language. These usually end in [.filename]#.el#, short for "
+"\"Emacs Lisp\". For example, if whizbang is a FreeBSD port, we can locate "
+"these files by doing"
+msgstr ""
+"Первое, что нужно сделать, — это выяснить, поставляются ли с whizbang какие-"
+"либо файлы, сообщающие Emacs о языке. Обычно они заканчиваются на "
+"[.filename]#.el#, что означает \"Emacs Lisp\". Например, если whizbang "
+"является портом FreeBSD, мы можем найти эти файлы, выполнив"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1574
+#, no-wrap
+msgid "% find /usr/ports/lang/whizbang -name \"*.el\" -print\n"
+msgstr "% find /usr/ports/lang/whizbang -name \"*.el\" -print\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1578
+msgid ""
+"and install them by copying them into the Emacs site Lisp directory. On "
+"FreeBSD, this is [.filename]#/usr/local/share/emacs/site-lisp#."
+msgstr ""
+"и установите их, скопировав в каталог Emacs, где находятся файлы Lisp (site "
+"Lisp). В FreeBSD это [.filename]#/usr/local/share/emacs/site-lisp#."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1580
+msgid "So for example, if the output from the find command was"
+msgstr "Вот пример, если вывод команды find был"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1584
+#, no-wrap
+msgid "/usr/ports/lang/whizbang/work/misc/whizbang.el\n"
+msgstr "/usr/ports/lang/whizbang/work/misc/whizbang.el\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1587
+msgid "we would do"
+msgstr "мы бы сделали"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1591
+#, no-wrap
+msgid "# cp /usr/ports/lang/whizbang/work/misc/whizbang.el /usr/local/share/emacs/site-lisp\n"
+msgstr "# cp /usr/ports/lang/whizbang/work/misc/whizbang.el /usr/local/share/emacs/site-lisp\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1596
+msgid ""
+"Next, we need to decide what extension whizbang source files have. Let us "
+"say for the sake of argument that they all end in [.filename]#.wiz#. We "
+"need to add an entry to our [.filename]#.emacs# to make sure Emacs will be "
+"able to use the information in [.filename]#whizbang.el#."
+msgstr ""
+"Далее нам нужно решить, какое расширение имеют исходные файлы whizbang. "
+"Допустим, для примера, что все они заканчиваются на [.filename]#.wiz#. Нам "
+"необходимо добавить запись в наш [.filename]#.emacs#, чтобы убедиться, что "
+"Emacs сможет использовать информацию из [.filename]#whizbang.el#."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1598
+msgid ""
+"Find the auto-mode-alist entry in [.filename]#.emacs# and add a line for "
+"whizbang, such as:"
+msgstr ""
+"Найдите запись auto-mode-alist в файле [.filename]#.emacs# и добавьте строку "
+"для whizbang, например:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1606
+#, no-wrap
+msgid ""
+"...\n"
+"(\"\\\\.lsp$\" . lisp-mode)\n"
+"(\"\\\\.wiz$\" . whizbang-mode)\n"
+"(\"\\\\.scm$\" . scheme-mode)\n"
+"...\n"
+msgstr ""
+"...\n"
+"(\"\\\\.lsp$\" . lisp-mode)\n"
+"(\"\\\\.wiz$\" . whizbang-mode)\n"
+"(\"\\\\.scm$\" . scheme-mode)\n"
+"...\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1609
+msgid ""
+"This means that Emacs will automatically go into `whizbang-mode` when you "
+"edit a file ending in [.filename]#.wiz#."
+msgstr ""
+"Это означает, что Emacs автоматически перейдёт в режим `whizbang-mode` при "
+"редактировании файла с расширением [.filename]#.wiz#."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1612
+msgid ""
+"Just below this, you will find the font-lock-auto-mode-list entry. Add "
+"`whizbang-mode` to it like so:"
+msgstr ""
+"Непосредственно ниже вы найдете запись font-lock-auto-mode-list. Добавьте "
+"`whizbang-mode` в нее следующим образом:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1619
+#, no-wrap
+msgid ""
+";; Auto font lock mode\n"
+"(defvar font-lock-auto-mode-list\n"
+" (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'whizbang-mode 'lisp-mode 'perl-mode 'scheme-mode)\n"
+" \"List of modes to always start in font-lock-mode\")\n"
+msgstr ""
+";; Auto font lock mode\n"
+"(defvar font-lock-auto-mode-list\n"
+" (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'whizbang-mode 'lisp-mode 'perl-mode 'scheme-mode)\n"
+" \"List of modes to always start in font-lock-mode\")\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1622
+msgid ""
+"This means that Emacs will always enable `font-lock-mode` (ie syntax "
+"highlighting) when editing a [.filename]#.wiz# file."
+msgstr ""
+"Это означает, что Emacs всегда будет включать `font-lock-mode` (т.е. "
+"подсветку синтаксиса) при редактировании файла [.filename]#.wiz#."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1625
+msgid ""
+"And that is all that is needed. If there is anything else you want done "
+"automatically when you open up [.filename]#.wiz#, you can add a `whizbang-"
+"mode hook` (see `my-scheme-mode-hook` for a simple example that adds `auto-"
+"indent`)."
+msgstr ""
+"И это всё, что требуется. Если вам нужно, чтобы что-то ещё выполнялось "
+"автоматически при открытии [.filename]#.wiz#, вы можете добавить `whizbang-"
+"mode hook` (см. `my-scheme-mode-hook` для простого примера, который "
+"добавляет `auto-indent`)."
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1627
+#, no-wrap
+msgid "Further Reading"
+msgstr "Для дальнейшего ознакомления"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1630
+msgid ""
+"For information about setting up a development environment for contributing "
+"fixes to FreeBSD itself, please see man:development[7]."
+msgstr ""
+"Для получения информации о настройке среды разработки для внесения "
+"исправлений в саму FreeBSD см. man:development[7]."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1632
+msgid ""
+"Brian Harvey and Matthew Wright _Simply Scheme_ MIT 1994. ISBN 0-262-08226-8"
+msgstr ""
+"Brian Harvey and Matthew Wright _Simply Scheme_ MIT 1994. ISBN 0-262-08226-8"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1633
+msgid "Randall Schwartz _Learning Perl_ O'Reilly 1993 ISBN 1-56592-042-2"
+msgstr "Randall Schwartz _Learning Perl_ O'Reilly 1993 ISBN 1-56592-042-2"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1634
+msgid ""
+"Patrick Henry Winston and Berthold Klaus Paul Horn _Lisp (3rd Edition)_ "
+"Addison-Wesley 1989 ISBN 0-201-08319-1"
+msgstr ""
+"Patrick Henry Winston and Berthold Klaus Paul Horn _Lisp (3rd Edition)_ "
+"Addison-Wesley 1989 ISBN 0-201-08319-1"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1635
+msgid ""
+"Brian W. Kernighan and Rob Pike _The Unix Programming Environment_ Prentice-"
+"Hall 1984 ISBN 0-13-937681-X"
+msgstr ""
+"Brian W. Kernighan and Rob Pike _The Unix Programming Environment_ Prentice-"
+"Hall 1984 ISBN 0-13-937681-X"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1636
+msgid ""
+"Brian W. Kernighan and Dennis M. Ritchie _The C Programming Language (2nd "
+"Edition)_ Prentice-Hall 1988 ISBN 0-13-110362-8"
+msgstr ""
+"Brian W. Kernighan and Dennis M. Ritchie _The C Programming Language (2nd "
+"Edition)_ Prentice-Hall 1988 ISBN 0-13-110362-8"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1637
+msgid ""
+"Bjarne Stroustrup _The C++ Programming Language_ Addison-Wesley 1991 ISBN "
+"0-201-53992-6"
+msgstr ""
+"Bjarne Stroustrup _The C++ Programming Language_ Addison-Wesley 1991 ISBN "
+"0-201-53992-6"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1638
+msgid ""
+"W. Richard Stevens _Advanced Programming in the Unix Environment_ Addison-"
+"Wesley 1992 ISBN 0-201-56317-7"
+msgstr ""
+"W. Richard Stevens _Advanced Programming in the Unix Environment_ Addison-"
+"Wesley 1992 ISBN 0-201-56317-7"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1638
+msgid ""
+"W. Richard Stevens _Unix Network Programming_ Prentice-Hall 1990 ISBN "
+"0-13-949876-1"
+msgstr ""
+"W. Richard Stevens _Unix Network Programming_ Prentice-Hall 1990 ISBN "
+"0-13-949876-1"