diff options
Diffstat (limited to 'documentation/content/ru/books/developers-handbook/tools')
-rw-r--r-- | documentation/content/ru/books/developers-handbook/tools/_index.adoc | 1428 | ||||
-rw-r--r-- | documentation/content/ru/books/developers-handbook/tools/_index.po | 4483 |
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" |