Bab 12. Pemrograman

# Bab 12. Pemrograman

Saya memberikan beberapa petunjuk bagi orang untuk belajar pemrograman pada sistem Debian yang cukup untuk melacak kode sumber yang dikemas. Berikut adalah paket penting dan paket dokumentasi yang sesuai untuk pemrograman.

Referensi daring tersedia dengan mengetik "`man nama`" setelah memasang paket `manpages` dan `manpages-dev`. Referensi daring untuk alat GNU tersedia dengan mengetik "`info nama_program`" setelah memasang paket dokumentasi yang bersangkutan. Anda mungkin perlu memasukkan arsip `contrib` dan `non-free` selain arsip `main` karena beberapa dokumentasi GFDL tidak dianggap sesuai dengan DFSG.

Harap pertimbangkan untuk menggunakan alat sistem kontrol versi. Lihat Bagian 10.5, “Git”.

| Awas
Jangan gunakan "`test`" sebagai nama berkas uji yang dapat dieksekusi. "`test`" adalah shell builtin.

| Perhatian
Anda harus memasang program perangkat lunak yang langsung dikompilasi dari sumber ke "`/usr/local`" atau "`/opt`" untuk menghindari tabrakan dengan program sistem.

| Tip
Contoh kode untuk membuat "Song 99 Bottles of Beer" mestinya memberi Anda ide bagus tentang hampir semua bahasa pemrograman.

## 12.1. Skrip shell

Skrip shell adalah berkas teks dengan bit eksekusi yang dihidupkan dan berisi perintah dalam format berikut.

    #!/bin/sh
     ... command lines

Baris pertama menentukan interpreter shell yang membaca dan mengeksekusi isi berkas ini.

Membaca skrip shell adalah cara terbaik untuk memahami cara kerja sistem seperti Unix. Di sini, saya memberikan beberapa petunjuk dan pengingat untuk pemrograman shell. Lihat "Kesalahan Shell" (https://www.greenend.org.uk/rjk/2001/04/shell.html) untuk belajar dari kesalahan.

Tidak seperti mode interaktif shell (lihat Bagian 1.5, “Perintah shell sederhana” dan Bagian 1.6, “Pemrosesan teks mirip Unix”), skrip shell sering menggunakan parameter, kondisional, dan loop.

### 12.1.1. Kompatibilitas shell POSIX

Banyak skrip sistem dapat diinterpretasi oleh salah satu shell POSIX (lihat Tabel 1.13, “Daftar program shell”).

- Shell POSIX non-interaktif baku "`/usr/bin/sh`" adalah symlink yang menunjuk ke `/usr/bin/dash` dan digunakan oleh banyak program sistem.

- Shell POSIX interaktif baku adalah `/usr/bin/bash`.

Hindari menulis skrip shell dengan bashisme atau zshisme agar membuatnya portabel di antara semua shell POSIX. Anda dapat memeriksanya menggunakan checkbashisms(1).

Tabel 12.1. Daftar bashisme khas

Baik: POSIX | Hindari: bashisme
--- | ---
`if [ "$foo" = "$bar" ] ; then …` | `if [ "$foo" == "$bar" ] ; then …`
`diff -u file.c.orig file.c` | `diff -u file.c{.orig,}`
`mkdir /foobar /foobaz` | `mkdir /foo{bar,baz}`
`funcname() { … }` | `function funcname() { … }`
format oktal: "`\377`" | format heksadesimal: "`\xff`"

Perintah "`echo`" harus digunakan dengan kehati-hatian berikut karena implementasinya berbeda di antara bawaan shell dan perintah eksternal.

- Hindari menggunakan opsi perintah apa pun kecuali "`-n`".

- Hindari menggunakan urutan escape dalam string karena penanganannya bervariasi.

| Catatan
Meskipun opsi "`-n`" bukan benar-benar sintaks POSIX, itu umumnya diterima.

| Tip
Gunakan perintah "`printf`" alih-alih perintah "`echo`" jika Anda perlu menanamkan urutan escape dalam string keluaran.

### 12.1.2. Parameter shell

Parameter shell khusus sering digunakan dalam skrip shell.

Tabel 12.2. Daftar parameter shell

parameter shell | nilai
--- | ---
`$0` | nama shell atau skrip shell
`$1` | argumen shell pertama
`$9` | argumen shell kesembilan
`$#` | cacah parameter posisional
`"$*"` | `"$1 $2 $3 $4 … "`
`"$@"` | `"$1" "$2" "$3" "$4" …`
`$?` | status keluar dari perintah terkini
`$$` | PID dari skrip shell ini
`$!` | PID dari pekerjaan latar belakang yang baru-baru ini dimulai

Ekspansi parameter dasar yang perlu diingat adalah sebagai berikut.

Tabel 12.3. Daftar ekspansi parameter shell

bentuk ekspresi parameter | nilai jika `var` diatur | nilai jika `var` tidak diatur
--- | --- | ---
`${var:-string}` | "`$var`" | "`string`"
`${var:+string}` | "`string`" | "`null`"
`${var:=string}` | "`$var`" | "`string`" (dan jalankan "`var=string`")
`${var:?string}` | "`$var`" | echo "`string`" ke stderr (dan keluar dengan kesalahan)

Di sini, titik dua "`:`" di semua operator ini sebenarnya opsional.

- dengan "`:`" operator = menguji keberadaan dan bukan null

- tanpa "`:`" operator = hanya menguji keberadaan

Tabel 12.4. Daftar substitusi parameter shell utama

bentuk substitusi parameter | hasil
--- | ---
`${var%suffix}` | menghapus pola akhiran terkecil
`${var%%suffix}` | menghapus pola akhiran terbesar
`${var#prefix}` | menghapus pola awalan terkecil
`${var##prefix}` | menghapus pola awalan terbesar

### 12.1.3. Kondisional Shell

Setiap perintah mengembalikan status keluar yang dapat digunakan untuk ekspresi bersyarat.

- Sukses: 0 ("Benar/True")

- Galat: bukan 0 ("Salah/False")

| Catatan
"0" dalam konteks kondisional shell berarti "Benar", sedangkan "0" dalam konteks kondisional C berarti "Salah".

| Catatan
"`[`" adalah setara dengan perintah `test`, yang mengevaluasi argumennya sampai "`]`" sebagai ekspresi bersyarat.

Idiom kondisionak dasar untuk diingat adalah sebagai berikut.

- `perintah && bila_sukses_jalankan_perintah_ini_juga || true`"

- "`perintah || bila_tidak_sukses_jalankan_perintah_ini_juga || true`"

- Cuplikan skrip multi-baris sebagai berikut

    if [ conditional_expression ]; then
     if_success_run_this_command
    else
     if_not_success_run_this_command
    fi

Di sini "`|| true`" di akhir diperlukan untuk memastikan skrip shell ini tidak keluar pada baris ini secara tidak sengaja ketika shell dipanggil dengan flag"`-e`".

Tabel 12.5. Daftar operator perbandingan berkas dalam ekspresi bersyarat

persamaan | kondisi yang mengembalikan logis benar (true)
--- | ---
`-e file` | berkas ada
`-d file` | berkas ada dan berupa direktori
`-f berkas` | berkas ada dan berupa berkas biasa
`-w file` | berkas ada dan dapat ditulis
`-x file` | berkas ada dan dapat dieksekusi
`file1 -nt file2` | berkas1 lebih baru dari berkas2 (modifikasi)
`file1 -ot file2` | berkas1 lebih tua dari berkas2 (modifikasi)
`file1 -ef file2` | berkas1 dan berkas2 berada di perangkat yang sama dan nomor inode yang sama

Tabel 12.6. Daftar operator perbandingan string dalam ekspresi bersyarat

persamaan | kondisi yang mengembalikan logis benar (true)
--- | ---
`-z str` | panjang str adalah nol
`-n str` | panjang str adalah bukan nol
`str1 = str2` | str1 dan str2 adalah sama
`str1 != str2` | str1 dan str2 tidak sama
`str1 < str2` | str1 diurut sebelum str2 (tergantung lokal)
`str1 > str2` | str1 diurut setelah str2 (tergantung lokal)

Operator perbandingan integer aritmatika dalam ekspresi bersyarat adalah "`-eq`", "`-ne`", "`-lt`", "`-le`", "`-gt`", dan "`-ge`".

### 12.1.4. Loop shell

Ada beberapa idiom pengulangan untuk digunakan dalam shell POSIX.

- "`for x in foo1 foo2 … ; do perintah ; done`" mengulang dengan menetapkan butir dari daftar "`foo1 foo2 …`" ke variabel "`x`" dan mengeksekusi "`perintah`".

- "`while condition ; do perintah ; done`" mengulangi "`perintah`" saat "`kondisi`" adalah benar.

- "`until condition ; do perintah ; done`" mengulangi "`perintah`" saat "`kondisi`" tidak benar.

- "`break`" memungkinkan untuk keluar dari pengulangan.

- "`continue`" memungkinkan untuk melanjutkan iterasi pengulangan berikutnya.

| Tip
Iterasi numerik bahasa mirip C dapat direalisasikan dengan menggunakan seq(1) sebagai generator "`foo1 foo2 ...`".

| Tip
Lihat Bagian 9.4.9, “Mengulangi perintah atas berkas”.

### 12.1.5. Variabel lingkungan shell

Beberapa variabel lingkungan populer untuk command prompt shell normal mungkin tidak tersedia di bawah lingkungan eksekusi skrip Anda.

- Untuk "`$USER`", gunakan "`$(id -un)`"

- Untuk "`$UID`", gunakan "`$(id -u)`"

- Untuk "`$HOME`", gunakan "`$(getent passwd "$(id -u)"|cut -d ":" -f 6)`" (ini juga berfungsi pada Bagian 4.5.2, “Manajemen sistem terpusat modern”)

### 12.1.6. Urutan pemrosesan baris perintah shell

Shell memproses skrip kira-kira sebagai urutan berikut.

- Shell membaca satu baris.

- Shell mengelompokkan bagian dari baris sebagai satu token jika berada di dalam `"…"` atau `'…'`.

- Shell memecah bagian lain dari suatu baris menjadi token dengan yang berikut.

  - Ruang kosong: `spasi tab ganti baris`

  - Karakter meta: `< > | ; & ( )`

- Shell memeriksa kata tetapan untuk setiap token untuk menyesuaikan perilakunya jika tidak dalam `"…"` atau `'…'`.

  - kata tetapan: `if then elif else fi for in while unless do done case esac`

- Shell mengekspansikan alias jika tidak dalam `"…"` atau `'…'`.

- Shell mengekspansikan tilde jika tidak dalam `"…"` atau `'…'`.

  - "`~`" → direktori rumah pengguna saat ini

  - "~`~pengguna`" → direktori rumah `pengguna`

- Shell mengekspansikan parameter ke nilainya jika tidak dalam `'…'`.

  - parameter: "`$PARAMETER`" atau "`${PARAMETER}` "

- Shell mengekspansikan substitusi perintah jika tidak dalam `'…'`.

  - "`$( command )`" → keluaran dari "`perintah`"

  - "`` perintah ``" → keluaran dari "`perintah`"

- Shell mengekspansikan pathname glob untuk mencocokkan nama berkas jika tidak dalam `"…"`" atau `'…'`.

  - `*` → sebarang karakter

  - `?` → satu karakter

  - `[...]` → salah satu karakter dalam "`...`"

- Shell mencari perintah dari yang berikut dan mengeksekusinya.

  - definisi fungsi

  - perintah builtin

  - berkas yang dapat dieksekusi dalam "`$PATH`"

- Shell pergi ke baris berikutnya dan mengulangi proses ini lagi dari puncak urutan ini.

Kutip tunggal dalam kutip ganda tidak berpengaruh.

Mengeksekusi "`set -x`" di shell atau menjalankan shell dengan opsi "`-x`" membuat shell mencetak semua perintah yang dieksekusi. Ini sangat berguna untuk debugging.

### 12.1.7. Program utilitas untuk skrip shell

Untuk membuat program shell Anda seportabel mungkin antar sistem Debian, adalah ide yang baik untuk membatasi program utilitas hanya ke yang disediakan oleh paket-paket esensial.

- "`aptitude search ~E`" menampilkan daftar paket-paket penting.

- "`dpkg -L nama_paket |grep '/man/man.*/'`" mencantumkan daftar halaman man untuk perintah yang ditawarkan oleh paket `nama_paket`.

Tabel 12.7. Daftar paket yang berisi program utilitas kecil untuk skrip shell

paket | popcon | ukuran | deskripsi
--- | --- | --- | ---
`dash` | V:928, I:998 | 207 | shell kecil dan cepat patuh POSIX untuk `sh`
`coreutils` | V:910, I:1000 | 17994 | Utilitas inti GNU
`grep` | V:779, I:1000 | 1297 | GNU `grep`, `egrep`, dan `fgrep`
`sed` | V:762, I:1000 | 987 | GNU `sed`
`mawk` | V:485, I:998 | 295 | `awk` yang kecil dan cepat
`debianutils` | V:936, I:997 | 225 | utilitas lain-lain khusus untuk Debian
`bsdutils` | V:445, I:1000 | 338 | utilitas dasar dari 4.4BSD-Lite
`bsdextrautils` | V:754, I:863 | 382 | utilitas tambahan dari 4.4BSD-Lite
`moreutils` | V:18, I:39 | 232 | utilitas Unix tambahan

| Tip
Meskipun `moreutils` mungkin tidak ada di luar Debian, ia menawarkan program kecil yang menarik. Yang paling menonjol adalah sponge(8) yang sangat berguna ketika Anda ingin menimpa berkas asli.

Lihat Bagian 1.6, “Pemrosesan teks mirip Unix” misalnya.

## 12.2. Scripting dalam bahasa yang diinterpretasi

Tabel 12.8. Daftar paket terkait interpreter

paket | popcon | ukuran | dokumentasi
--- | --- | --- | ---
`dash` | V:928, I:998 | 207 | sh: shell kecil dan cepat patuh POSIX untuk `sh`
`bash` | V:893, I:1000 | 7309 | sh: "`info bash`" disediakan oleh `bash-doc`
`mawk` | V:485, I:998 | 295 | AWK: `awk` yang kecil dan cepat
`gawk` | V:250, I:301 | 3289 | AWK: "`info gawk`" disediakan oleh `gawk-doc`
`perl` | V:673, I:992 | 836 | Perl: perl(1) dan halaman html disediakan oleh `perl-doc` dan `perl-doc-html`
`libterm-readline-gnu-perl` | V:2, I:27 | 439 | Ekstensi Perl untuk GNU ReadLine/History Library: perlsh(1)
`libreply-perl` | V:0.01, I:0.10 | 171 | REPL untuk Perl: reply(1)
`libdevel-repl-perl` | V:0.03, I:0.57 | 237 | REPL untuk Perl: re.pl(1)
`python3` | V:717, I:974 | 80 | Python: python3(1) dan halaman html yang disediakan oleh `python3-doc`
`tcl` | V:23, I:176 | 20 | Tcl: tcl(3) dan detail halaman manual yang disediakan oleh `tcl-doc`
`tk` | V:17, I:169 | 20 | Tk: tk(3) dan detail halaman manual yang disediakan oleh `tk-doc`
`ruby` | V:71, I:157 | 32 | Ruby: ruby(1), erb(1), irb(1), rdoc(1), ri(1)

Ketika Anda ingin mengotomatiskan tugas di Debian, Anda harus menulisnya dengan bahasa yang diintepretasi terlebih dahulu. Panduan untuk pilihan bahasa yang diinterpretasi adalah:

- Gunakan `dash`, jika tugas sederhana yang menggabungkan program CLI dengan program shell.

- Gunakan `python3`, jika tugas tidak sederhana dan Anda menulisnya dari awal.

- Gunakan `perl`, `tcl`, `ruby`, ... jika sudah ada kode yang menggunakan salah satu bahasa ini di Debian yang perlu disentuh untuk melakukan tugas tersebut.

Jika kode yang dihasilkan terlalu lambat, Anda dapat menulis ulang hanya bagian penting untuk kecepatan eksekusi dalam bahasa yang dikompilasi dan memanggilnya dari bahasa yang ditafsirkan.

### 12.2.1. Debugging kode bahasa yang diinterpretasi

Sebagian besar interpreter menawarkan pemeriksaan sintaks dasar dan fungsi pelacakan kode.

- "dash -n script.sh" - Pemeriksaan sintaks dari suatu skrip Shell

- "dash -x script.sh"" - Melacak suatu skrip Shell

- "python -m py_compile script.py"" - Pemeriksaan sintaks skrip Python

- "python -mtrace --trace script.py"" - Melacak suatu skrip Python

- "perl -I .. /libpath -c script.pl"" - Pemeriksaan sintaks dari suatu skrip Perl

- "perl -d:Trace script.pl" - Melacak suatu skrip Perl

Untuk menguji kode bagi `dash`, cobalah Bagian 9.1.4, “Pembungkus readline” yang mengakomodasi lingkungan interaktif mirip `bash`.

Untuk menguji kode bagi `perl`, cobalah lingkungan REPL untuk Perl yang mengakomodasi lingkungan mirip Python REPL (= READ + EVAL + PRINT + LOOP) untuk Perl.

### 12.2.2. Program GUI dengan skrip shell

Skrip shell dapat diperbaiki untuk membuat program GUI yang menarik. Caranya adalah dengan menggunakan salah satu program dialog yang disebut alih-alih interaksi membosankan menggunakan perintah `echo` dan `read`.

Tabel 12.9. Daftar program dialog

paket | popcon | ukuran | deskripsi
--- | --- | --- | ---
`x11-utils` | V:222, I:551 | 651 | xmessage(1): menampilkan pesan atau kueri di jendela (X)
`whiptail` | V:303, I:997 | 61 | menampilkan kotak dialog yang mudah digunakan dari skrip shell (newt)
`dialog` | V:8, I:77 | 520 | menampilkan kotak dialog yang mudah digunakan dari skrip shell (ncurses)
`zenity` | V:74, I:338 | 193 | menampilkan kotak dialog grafis dari skrip shell (GTK)
`ssft` | V:0.01, I:0.16 | 80 | Shell Scripts Frontend Tool (pembungkus untuk zenity, kdialog, dan dialog dengan gettext)
`gettext` | V:51, I:216 | 20468 | "`/usr/bin/gettext.sh`": terjemahkan pesan

Berikut adalah contoh program GUI untuk menunjukkan betapa mudahnya itu hanya dengan suatu skrip shell.

Skrip ini menggunakan `zenity` untuk memilih berkas (baku `/etc/motd)` dan menampilkannya.

Peluncur GUI untuk skrip ini dapat dibuat berikut Bagian 9.4.10, “Memulai program dari GUI”.

    #!/bin/sh -e
    # Copyright (C) 2021 Osamu Aoki <osamu@debian.org>, Public Domain
    # vim:set sw=2 sts=2 et:
    DATA_FILE=$(zenity --file-selection --filename="/etc/motd" --title="Select a file to check") || \
      ( echo "E: File selection error" >&2 ; exit 1 )
    # Check size of archive
    if ( file -ib "$DATA_FILE" | grep -qe '^text/' ) ; then
      zenity --info --title="Check file: $DATA_FILE" --width 640  --height 400 \
        --text="$(head -n 20 "$DATA_FILE")"
    else
      zenity --info --title="Check file: $DATA_FILE" --width 640  --height 400 \
        --text="The data is MIME=$(file -ib "$DATA_FILE")"
    fi

Pendekatan semacam ini untuk program GUI dengan skrip shell hanya berguna untuk kasus pilihan sederhana. Jika Anda ingin menulis program apa pun dengan kompleksitas, silakan pertimbangkan untuk menulisnya di platform yang lebih mampu.

### 12.2.3. Tindakan ubahan untuk filer GUI

Program filer GUI dapat diperluas untuk melakukan beberapa tindakan populer pada berkas yang dipilih menggunakan paket ekstensi tambahan. Mereka juga dapat dibuat untuk melakukan tindakan ubahan yang sangat spesifik dengan menambahkan skrip spesifik Anda.

- Untuk GNOME, lihat NautilusScriptsHowto.

- Untuk KDE, lihat Membuat Menu Layanan Dolphin.

- Untuk Xfce, lihat Thunar - Tindakan Ubahan dan https://help.ubuntu.com/community/ThunarCustomActions.

- Untuk LXDE, lihat Tindakan Ubahan.

### 12.2.4. Kegilaan skrip pendek Perl

Untuk memproses data, `sh` perlu men-spawn sub-proses yang menjalankan `cut`, `grep`, `sed`, dll, dan lambat. Di sisi lain, `perl` memiliki kemampuan internal untuk memroses data, dan cepat. Begitu banyak skrip pemeliharaan sistem pada Debian menggunakan `perl`.

Mari kita pikirkan untuk mengikuti cuplikan skrip AWK satu-baris dan yang setara di Perl.

    awk '($2=="1957") { print $3 }' |

Ini setara dengan salah satu dari baris berikut.

    perl -ne '@f=split; if ($f[1] eq "1957") { print "$f[2]\n"}' |

    perl -ne 'if ((@f=split)[1] eq "1957") { print "$f[2]\n"}' |

    perl -ne '@f=split; print $f[2] if ( $f[1]==1957 )' |

    perl -lane 'print $F[2] if $F[1] eq "1957"' |

    perl -lane 'print$F[2]if$F[1]eq+1957' |

Yang terakhir adalah teka-teki. Itu mengambil keuntungan dari mengikuti fitur Perl.

- Ruang kosong (whitespace) adalah opsional.

- Konversi otomatis ada dari angka ke string.

- Trik eksekusi perl melalui opsi baris perintah: perlrun(1)

- Variabel khusus Perl: perlvar(1)

Fleksibilitas ini adalah kekuatan Perl. Pada saat yang sama, ini memungkinkan kita untuk membuat kode sulit dibaca dan kusut. Jadi berhati-hatilah.

## 12.3. Menuis kode dalam bahasa yang dikompilasi

Tabel 12.10. Daftar paket terkait kompiler

paket | popcon | ukuran | deskripsi
--- | --- | --- | ---
`gcc` | V:155, I:564 | 36 | Kompiler GNU C
`libc6-dev` | V:269, I:584 | 12861 | GNU C Library: Pustaka Pengembangan dan Berkas Header
`g++` | V:57, I:531 | 13 | Kompiler GNU C++
`libstdc++-16-dev` | V:0.7, I:4.3 | 24382 | GNU Standard C++ Library v3 (berkas pengembangan)
`cpp` | V:332, I:719 | 18 | Preprocessor C GNU
`gettext` | V:51, I:216 | 20468 | Utilitas internasionalisasi GNU
`glade` | V:0.7, I:2.7 | 1613 | Pembangun Antarmuka Pengguna GTK
`valac` | V:0.2, I:3.2 | 533 | Bahasa mirip C# untuk sistem GObject
`flex` | V:7, I:68 | 1247 | Kompatibel LEX fast lexical analyzer generator
`bison` | V:7, I:73 | 3122 | Kompatibel YACC parser generator
`susv2` | I:0.03 | 16 | ambil "The Single UNIX Specifications v2"
`susv3` | I:0.06 | 16 | ambil "The Single UNIX Specifications v3"
`susv4` | I:0.04 | 16 | ambil "The Single UNIX Specifications v4"
`golang` | I:22 | 12 | Kompiler bahasa pemrograman Go
`rustc` | V:5, I:20 | 13061 | Bahasa pemrograman sistem Rust
`gfortran` | V:4, I:50 | 15 | Kompiler GNU Fortran 95
`fpc` | I:2.3 | 101 | Free Pascal

Di sini, Bagian 12.3.3, “Flex - Lex yang lebih baik” dan Bagian 12.3.4, “Bison - Yacc yang lebih baik” disertakan untuk menunjukkan bagaimana program seperti kompiler dapat ditulis dalam bahasa C dengan menyusun deskripsi tingkat yang lebih tinggi ke dalam bahasa C.

### 12.3.1. C

Anda dapat mengatur lingkungan yang tepat untuk mengkompilasi program yang ditulis dalam bahasa pemrograman C dengan yang berikut.

    # apt-get install glibc-doc manpages-dev libc6-dev gcc build-essential

Paket `libc6-dev`, yaitu Pustaka GNU C, menyediakan pustaka standar C yang merupakan kumpulan berkas header dan pustaka fungsi yang digunakan oleh bahasa pemrograman C.

Lihat referensi untuk C dengan cara berikut.

- "`info libc`" (referensi fungsi pustaka C)

- gcc(1) dan "`info gcc`"

- each_C_library_function_name(3)

- Kernighan & Ritchie, "The C Programming Language", 2nd edition (Prentice Hall)

### 12.3.2. Program C Sederhana (gcc)

Contoh sederhana "`example.c`" dapat dikompilasi dengan pustaka "`libm`" menjadi "`run_example`" yang dapat dieksekusi dengan berikut.

    $ cat > example.c << EOF
    #include <stdio.h>
    #include <math.h>
    #include <string.h>

    int main(int argc, char **argv, char **envp){
            double x;
            char y[11];
            x=sqrt(argc+7.5);
            strncpy(y, argv[0], 10); /* prevent buffer overflow */
            y[10] = '\0'; /* fill to make sure string ends with '\0' */
            printf("%5i, %5.3f, %10s, %10s\n", argc, x, y, argv[1]);
            return 0;
    }
    EOF
    $ gcc -Wall -g -o run_example example.c -lm
    $ ./run_example
            1, 2.915, ./run_exam,     (null)
    $ ./run_example 1234567890qwerty
            2, 3.082, ./run_exam, 1234567890qwerty

Di sini, "`-lm`" diperlukan untuk me-link pustaka "`/usr/lib/libm.so`" dari paket `libc6` untuk sqrt(3). Pustaka yang sebenarnya adalah dalam "`/lib/`" dengan nama berkas "`libm.so.6`", yang merupakan symlink untuk "`libm-2.7.so`".

Lihatlah parameter terakhir dalam teks keluaran. Ada lebih dari 10 karakter meskipun "`%10s`" ditentukan.

Penggunaan fungsi operasi memori pointer tanpa pemeriksaan batas, seperti sprintf(3) dan strcpy(3), tidak berlaku lagi untuk mencegah eksploitasi buffer overflow yang memanfaatkan efek overrun di atas. Sebagai gantinya, gunakan snprintf(3) dan strncpy(3).

### 12.3.3. Flex - Lex yang lebih baik

Flex adalah generator analisis leksikal cepat yang kompatibel dengan Lex.

Tutorial untuk flex(1) dapat ditemukan di "`info flex`".

Banyak contoh sederhana dapat ditemukan di bawah "`/usr/share/doc/flex/examples/`". [7]

### 12.3.4. Bison - Yacc yang lebih baik

Beberapa paket menyediakan parser LR lookahead yang kompatibel dengan Yacc atau generator parser LALR di Debian.

Tabel 12.11. Daftar generator parser LALR yang kompatibel dengan Yacc

paket | popcon | ukuran | deskripsi
--- | --- | --- | ---
`bison` | V:7, I:73 | 3122 | Generator parser GNU LALR
`byacc` | V:0.1, I:3.0 | 263 | Generator parser Berkeley LALR
`btyacc` | V:0.01, I:0.06 | 247 | backtracking parser generator berdasarkan `byacc`

Tutorial untuk bison(1) dapat ditemukan di"`info bison`".

Anda perlu menyediakan "`main()`" dan "`yyerror()`" Anda sendiri. "`main()`" memanggil "`yyparse()`" yang memanggil "`yylex()`", biasanya dibuat dengan Flex.

Berikut ini adalah contoh untuk membuat program kalkulator terminal sederhana.

Mari kita buat `example.y`:

    /* calculator source for bison */
    %{
    #include <stdio.h>
    extern int yylex(void);
    extern int yyerror(char *);
    %}

    /* declare tokens */
    %token NUMBER
    %token OP_ADD OP_SUB OP_MUL OP_RGT OP_LFT OP_EQU

    %%
    calc:
     | calc exp OP_EQU    { printf("Y: RESULT = %d\n", $2); }
     ;

    exp: factor
     | exp OP_ADD factor  { $$ = $1 + $3; }
     | exp OP_SUB factor  { $$ = $1 - $3; }
     ;

    factor: term
     | factor OP_MUL term { $$ = $1 * $3; }
     ;

    term: NUMBER
     | OP_LFT exp OP_RGT  { $$ = $2; }
      ;
    %%

    int main(int argc, char **argv)
    {
      yyparse();
    }

    int yyerror(char *s)
    {
      fprintf(stderr, "error: '%s'\n", s);
    }

Mari kita buat, `example.l`:

    /* calculator source for flex */
    %{
    #include "example.tab.h"
    %}

    %%
    [0-9]+ { printf("L: NUMBER = %s\n", yytext); yylval = atoi(yytext); return NUMBER; }
    "+"    { printf("L: OP_ADD\n"); return OP_ADD; }
    "-"    { printf("L: OP_SUB\n"); return OP_SUB; }
    "*"    { printf("L: OP_MUL\n"); return OP_MUL; }
    "("    { printf("L: OP_LFT\n"); return OP_LFT; }
    ")"    { printf("L: OP_RGT\n"); return OP_RGT; }
    "="    { printf("L: OP_EQU\n"); return OP_EQU; }
    "exit" { printf("L: exit\n");   return YYEOF; } /* YYEOF = 0 */
    .      { /* ignore all other */ }
    %%

Kemudian jalankan perintah berikut ini dari prompt shell untuk mencobanya:

    $ bison -d example.y
    $ flex example.l
    $ gcc -lfl example.tab.c lex.yy.c -o example
    $ ./example
    1 + 2 * ( 3 + 1 ) =
    L: NUMBER = 1
    L: OP_ADD
    L: NUMBER = 2
    L: OP_MUL
    L: OP_LFT
    L: NUMBER = 3
    L: OP_ADD
    L: NUMBER = 1
    L: OP_RGT
    L: OP_EQU
    Y: RESULT = 9

    exit
    L: exit

## 12.4. Alat analisis kode statis

Alat seperti Lint dapat membantu analisis kode statisotomatis.

Alat seperti indent dapat membantu peninjauan kode dengan memformat ulang kode sumber secara konsisten.

Alat seperti Ctags dapat membantu peninjauan kode dengan menghasilkan berkas indeks (atau tag) nama yang ditemukan dalam kode sumber.

| Tip
Mengonfigurasi penyunting favorit Anda (`emacs` atau `vim`) untuk menggunakan plugin mesin lint asinkron membantu penulisan kode Anda. Plugin ini menjadi sangat kuat dengan memanfaatkan Language Server Protocol. Karena mereka bergerak cepat, menggunakan kode hulu mereka, bukan paket Debian mungkin merupakan pilihan yang baik.

Tabel 12.12. Daftar alat untuk analisis kode statis

paket | popcon | ukuran | deskripsi
--- | --- | --- | ---
`vim-ale` | I:0.80 | 2833 | Asynchronous Lint Engine untuk Vim 8 dan NeoVim
`vim-syntastic` | I:2.0 | 1379 | Hack pemeriksaan sintaks untuk vim
`elpa-flycheck` | V:0.1, I:1.7 | 1130 | pemeriksaan sintaks sambil jalan modern untuk Emacs
`elpa-relint` | I:0.06 | 150 | Pencari kesalahan regex Emacs Lisp
`cppcheck-gui` | V:0.1, I:1.0 | 7697 | alat untuk analisis kode C/C++ statis (GUI)
`shellcheck` | V:3, I:16 | 22860 | alat lint untuk skrip shell
`pyflakes3` | V:1, I:12 | 20 | pemeriksa pasif dari program Python 3
`pylint` | V:3, I:17 | 2093 | Pemeriksa statis kode python
`perl` | V:673, I:992 | 836 | interpreter dengan pemeriksa kode statis internal: `B::Lint`(3perl)
`rubocop` | V:0.1, I:1.1 | 4192 | Penganalisis kode statis Ruby
`clang-tidy` | V:2, I:10 | 21 | alat linter C++ berbasis clang
`splint` | V:0.06, I:0.92 | 2325 | alat untuk memeriksa secara statis program C untuk bug
`flawfinder` | V:0.07, I:0.49 | 187 | alat untuk memeriksa kode sumber C/C++ dan mencari kelemahan keamanan
`black` | V:2, I:13 | 10057 | pemformat kode Python tanpa kompromi
`perltidy` | V:0.4, I:3.1 | 3086 | Pengindentasi dan pemformat ulang skrip Perl
`indent` | V:0.8, I:5.1 | 438 | program pemformatan kode sumber bahasa C
`astyle` | V:0.2, I:2.7 | 770 | Pengindentasi kode sumber untuk C, C++, Objective-C, C#, dan Java
`bcpp` | V:0.02, I:0.26 | 114 | pemercantik C(++)
`xmlindent` | V:0.05, I:0.79 | 52 | Pemformat ulang stream XML
`global` | V:0.2, I:1.6 | 1923 | Alat pencarian dan penelusuran kode sumber
`exuberant-ctags` | V:2, I:13 | 341 | membangun indeks berkas tag atas definisi kode sumber
`universal-ctags` | V:2, I:10 | 4238 | membangun indeks berkas tag atas definisi kode sumber

## 12.5. Awakutu

Debug adalah bagian penting dari kegiatan pemrograman. Mengetahui cara men-debug program membuat Anda pengguna Debian yang baik yang dapat menghasilkan laporan bug yang berarti.

Tabel 12.13. Daftar paket debug

paket | popcon | ukuran | dokumentasi
--- | --- | --- | ---
`gdb` | V:88, I:161 | 12453 | "`info gdb`" disediakan oleh `gdb-doc`
`ddd` | V:0.7, I:5.2 | 4210 | "`info ddd`" disediakan oleh `ddd-doc`

### 12.5.1. Eksekusi gdb dasar

Debugger utama pada Debian adalah gdb(1) yang memungkinkan Anda untuk menginspeksi program saat dijalankan.

Mari kita pasang `gdb` dan program terkait dengan yang berikut ini.

    # apt-get install gdb gdb-doc build-essential devscripts

Tutorial yang baik dari `gdb` dapat ditemukan:

- “`info gdb`”

- "Debugging dengan GDB" di `/usr/share/doc/gdb-doc/html/gdb/index.html`

- “tutorial di web”

Berikut adalah contoh sederhana menggunakan gdb(1) pada suatu "`program`" yang dikompilasi dengan opsi "`-g`" untuk menghasilkan informasi debugging.

    $ gdb program
    (gdb) b 1                # set break point at line 1
    (gdb) run args           # run program with args
    (gdb) next               # next line
    ...
    (gdb) step               # step forward
    ...
    (gdb) p parm             # print parm
    ...
    (gdb) p parm=12          # set value to 12
    ...
    (gdb) quit

| Tip
Banyak perintah gdb(1) dapat disingkat. Ekspansi tab bekerja seperti di shell.

### 12.5.2. Debugging paket Debian

Karena semua biner yang dipasang harus di-strip pada sistem Debian secara baku, sebagian besar simbol debug dihapus dalam paket normal. Untuk men-debug paket Debian dengan gdb(1), paket `*-dbgsym` perlu dipasang (misalnya `coreutils-dbgsym` dalam kasus `coreutils).` Paket sumber menghasilkan paket `*-dbgsym` secara otomatis bersama dengan paket biner normal dan paket debug tersebut ditempatkan secara terpisah dalam arsip debian-debug. Silakan merujuk ke artikel di Debian Wiki untuk informasi lebih lanjut.

Jika paket yang akan di-debug tidak menyediakan paket `*-dbgsym`, Anda perlu memasangnya setelah membangun kembali dengan yang berikut.

    $ mkdir /path/new ; cd /path/new
    $ sudo apt-get update
    $ sudo apt-get dist-upgrade
    $ sudo apt-get install fakeroot devscripts build-essential
    $ apt-get source package_name
    $ cd package_name*
    $ sudo apt-get build-dep ./

Perbaiki bug jika diperlukan.

Bump versi paket ke yang tidak bertabrakan dengan versi Debian resmi, misalnya yang ditambahi "`+debug1`" ketika meng-compile ulang versi paket yang ada, atau yang ditambahi "`~ pre1`" ketika meng-compile versi paket yang belum pernah dirilis dengan yang berikut.

    $ dch -i

Kompilasi dan install paket beserta simbol debug dengan yang berikut ini.

    $ export DEB_BUILD_OPTIONS="nostrip noopt"
    $ debuild
    $ cd ..
    $ sudo debi package_name*.changes

Anda perlu memeriksa skrip build paket dan memastikan menggunakan "`CFLAGS = -g -Wall`" untuk mengkompilasi biner.

### 12.5.3. Mendapatkan backtrace

Ketika Anda mengalami crash program, melaporkan laporan kutu dengan informasi backtrace yang dipotong-dan-tempel adalah ide yang baik.

Backtrace dapat diperoleh dengan gdb(1) menggunakan salah satu pendekatan berikut:

- Pendekatan Crash-in-GDB:

  - Jalankan program dari GDB.

  - Menjadikan program crash.

  - Ketik "`bt`" pada prompt GDB.

- Pendekatan crash-first:

  - Perbarui berkas "/etc/security/limits.conf" untuk menyertakan hal-hal berikut:

        * soft core unlimited

  - Ketik "`ulimit -c unlimited`" ke prompt shell.

  - Menjalankan program dari prompt shell ini.

  - Crash-kan program untuk menghasilkan berkas core dump.

  - Muat berkas core dump ke GDB sebagai "`gdb gdb ./biner_program core`".

  - Ketik "`bt`" pada prompt GDB.

Untuk pengulangan tak hingga atau situasi papan ketik beku, Anda dapat memaksa untuk program crash dengan menekan `Ctrl-\` atau `Ctrl-C` atau mengeksekusi"`kill -ABRT PID` ". (Lihat Bagian 9.4.12, “Membunuh sebuah proses”)

| Tip

Seringkali, Anda melihat backtrace dimana satu atau lebih dari baris atas berada dalam "`malloc()`" atau"`g_malloc()`". Ketika ini terjadi, kemungkinan backtrace Anda tidak terlalu berguna. Cara termudah untuk menemukan beberapa informasi yang berguna adalah dengan mengatur variabel lingkungan "`$MALLOC_CHECK_`" ke nilai 2 (malloc(3)). Anda dapat melakukan ini saat sedang menjalankan `gdb` dengan melakukan hal berikut.

     $ MALLOC_CHECK_=2 gdb hello

### 12.5.4. Perintah gdb tingkat lanjut

Tabel 12.14. Daftar perintah gdb tingkat lanjut

perintah | deskripsi untuk tujuan perintah
--- | ---
`(gdb) thread apply all bt` | mendapatkan backtrace untuk semua thread bagi program multi-thread
`(gdb) bt full` | mendapatkan parameter yang ada pada stack pemanggilan fungsi
`(gdb) thread apply all bt full` | mendapatkan backtrace dan parameter sebagai kombinasi dari opsi sebelumnya
`(gdb) thread apply all bt full 10` | mendapatkan backtrace dan parameter untuk 10 panggilan teratas untuk memotong keluaran yang tidak relevan
`(gdb) set logging on` | menulis log keluaran `gdb` ke berkas (bakunya adalah "`gdb.txt`")

### 12.5.5. Periksa ketergantungan pada pustaka

Gunakan ldd(1) untuk mengetahui ketergantungan program pada pustaka dengan yang berikut ini.

    $ ldd /usr/bin/ls
            librt.so.1 => /lib/librt.so.1 (0x4001e000)
            libc.so.6 => /lib/libc.so.6 (0x40030000)
            libpthread.so.0 => /lib/libpthread.so.0 (0x40153000)
            /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

Agar ls(1) bekerja di lingkungan 'chroot', pustaka di atas harus tersedia di lingkungan 'chroot' Anda.

Lihat Bagian 9.4.6, “Menelusuri aktivitas program”.

### 12.5.6. Alat pelacakan panggilan dinamis

Ada beberapa alat pelacakan panggilan dinamis yang tersedia di Debian. Lihat Bagian 9.4, “Memantau, mengendalikan, dan memulai aktivitas program”.

### 12.5.7. Men-debug Galat X

Jika sebuah program GNOME `preview1` telah menerima kesalahan X, Anda akan melihat pesan sebagai berikut.

    The program 'preview1' received an X Window System error.

Jika ini masalahnya, Anda dapat mencoba menjalankan program dengan "`--sync`", dan memutus pada fungsi "`gdk_x_error`"untuk mendapatkan backtrace.

### 12.5.8. Alat deteksi kebocoran memori

Ada beberapa alat deteksi kebocoran memori yang tersedia di Debian.

Tabel 12.15. Daftar alat deteksi kebocoran memori

paket | popcon | ukuran | deskripsi
--- | --- | --- | ---
`libc6-dev` | V:269, I:584 | 12861 | mtrace(1): fungsi debugging malloc di glibc
`valgrind` | V:4, I:31 | 89318 | debugger dan profiler memori
`electric-fence` | V:0.2, I:2.3 | 69 | malloc(3) debugger
`libdmalloc5` | V:0.01, I:0.61 | 373 | debug pustaka alokasi memori
`duma` | V:0.00, I:0.06 | 297 | pustaka untuk mendeteksi buffer overrun dan under-run dalam program C dan C++
`leaktracer` | V:0.01, I:0.33 | 56 | pelacak kebocoran memori untuk program C++

### 12.5.9. Disassembly biner

Anda dapat men-disassembly kode biner memakai objdump(1) dengan yang berikut ini.

    $  objdump -m i386 -b binary -D /usr/lib/grub/x86_64-pc/stage1

| Catatan
gdb(1) dapat digunakan untuk men-disassembly kode secara interaktif.

## 12.6. Alat build

Tabel 12.16. Daftar paket alat build

paket | popcon | ukuran | dokumentasi
--- | --- | --- | ---
`make` | V:150, I:566 | 1762 | "`info make`" disediakan oleh `make-doc`
`autoconf` | V:29, I:200 | 2244 | "`info autoconf`" disediakan oleh `autoconf-doc`
`automake` | V:28, I:199 | 1932 | "`info automake`" disediakan oleh `automake1.10-doc`
`libtool` | V:24, I:183 | 1245 | "`info libtool`" disediakan oleh `libtool-doc`
`cmake` | V:21, I:123 | 59735 | cmake(1) sistem make open-source yang lintas platform
`ninja-build` | V:9, I:55 | 456 | ninja(1) sistem build kecil yang paling dekat dalam semangat ke Make
`meson` | V:6, I:29 | 4278 | meson(1) sistem build produktivitas tinggi di atas `ninja`
`xutils-dev` | V:0.9, I:7.0 | 1495 | imake(1), xmkmf(1), etc.

### 12.6.1. Make

Make adalah utilitas untuk memelihara kelompok program. Saat eksekusi make(1), `make` membaca berkas aturan, "`Makefile`", dan memperbarui target jika itu tergantung pada berkas prasyarat yang telah dimodifikasi sejak target terakhir dimodifikasi, atau jika target tidak ada. Pelaksanaan pembaruan ini dapat terjadi secara bersamaan.

Sintaks berkas aturan adalah sebagai berikut.

    target: [ prerequisites ... ]
     [TAB]  command1
     [TAB]  -command2 # ignore errors
     [TAB]  @command3 # suppress echoing

Di sini "`[TAB]`" adalah kode TAB. Setiap baris ditafsirkan oleh shell setelah membuat substitusi variabel. Gunakan "`\`" di akhir baris untuk melanjutkan skrip. Gunakan "`$$`" untuk memasukkan "`$`" bagi nilai lingkungan untuk skrip shell.

Aturan implisit untuk target dan prasyarat dapat ditulis, misalnya, dengan yang berikut.

    %.o: %.c header.h

Di sini, target berisi karakter "`%`" (tepat satu dari mereka). "`%`" bisa cocok dengan sebarang sub string tidak kosong dalam nama berkas target yang sebenarnya. Prasyarat juga menggunakan "`%`" untuk menunjukkan bagaimana nama mereka berhubungan dengan nama target yang sebenarnya.

Tabel 12.17. Daftar variabel otomatis make

variabel otomatis | nilai
--- | ---
`$@` | target
`$<` | prasyarat pertama
`$?` | semua prasyarat yang lebih baru
`$^` | semua prasyarat
`$*` | "`%`" cocok dengan stem dalam pola target

Tabel 12.18. Daftar ekspansi variabel make

ekspansi variabel | deskripsi
--- | ---
`foo1 := bar` | ekspansi satu kali
`foo2 = bar` | ekspansi rekursif
`foo3 += bar` | tambah

Jalankan "`make -p -f/dev/null`" untuk melihat aturan internal otomatis.

### 12.6.2. Autotools

Autotools adalah keluarga alat pemrograman yang dirancang untuk membantu dalam membuat paket kode sumber portabel ke banyak sistem mirip Unix.

- Autoconf adalah alat untuk menghasilkan skrip shell "`configure`" dari "`configure.ac`".

  - "`configure`" digunakan kemudian untuk menghasilkan "`Makefile`" dari templat "`Makefile.in`".

- Automake adalah alat untuk menghasilkan"`Makefile.in`" dari "`Makefile.am`".

- Libtool adalah skrip shell untuk mengatasi masalah portabilitas perangkat lunak saat menyusun pustaka bersama dari kode sumber.

#### 12.6.2.1. Mengkompilasi dan menginstall program

| Awas
Jangan menimpa berkas sistem dengan program yang dikompilasi saat menginstalnya.

Debian tidak menyentuh berkas di "`/usr/local/`" atau "`/opt`". Jadi jika Anda mengkompilasi program dari sumber, pasang saja ke "`/usr/local/`" sehingga tidak mengganggu Debian.

    $ cd src
    $ ./configure --prefix=/usr/local
    $ make # this compiles program
    $ sudo make install # this installs the files in the system

#### 12.6.2.2. Menghapus instalasi program

Jika Anda memiliki sumber asli dan jika itu menggunakan autoconf(1)/automake(1) dan jika Anda dapat mengingat bagaimana Anda mengonfigurasinya, jalankan sebagai berikut untuk menghapus instalasi program.

    $ ./configure all-of-the-options-you-gave-it
    $ sudo make uninstall

Atau, jika Anda benar-benar yakin bahwa proses instalasi menempatkan berkas hanya di bawah "`/usr/local/`" dan tidak ada yang penting di sana, Anda dapat menghapus semua isinya dengan berikut ini.

    # find /usr/local -type f -print0 | xargs -0 rm -f

Jika Anda tidak yakin di mana berkas dipasang, Anda harus mempertimbangkan untuk menggunakan checkinstall(8) dari paket `checkinstall`, yang menyediakan path bersih untuk pembongkaran. Itu sekarang mendukung untuk membuat paket Debian dengan opsi "`-D`".

### 12.6.3. Meson

Sistem build perangkat lunak telah berkembang:

- Autotools di bagian atas Make telah menjadi standar de facto untuk infrastruktur bangunan portabel sejak 1990-an. Ini sangat lambat.

- CMake awalnya dirilis pada tahun 2000 meningkatkan kecepatan secara signifikan tetapi aslinya dibangun di atas Make yang inheren lambat. Kini Ninja bisa menjadi backend-nya.)

- Ninja awalnya dirilis pada tahun 2012 dimaksudkan untuk menggantikan Make untuk kecepatan build yang lebih ditingkatkan tetapi juga dirancang untuk memiliki berkas masukan yang dihasilkan oleh sistem build tingkat yang lebih tinggi.

- Meson awalnya dirilis pada tahun 2013 adalah sistem build tingkat tinggi yang baru, populer, dan cepat yang menggunakan Ninja sebagai backend-nya.

Lihat dokumen yang ditemukan di "The Meson Build system" dan "The Ninja build system".

## 12.7. Web

Halaman web dinamis interaktif dasar dapat dibuat sebagai berikut.

- Kueri disajikan kepada pengguna peramban menggunakan formulir HTML.

- Mengisi dan mengklik entri formulir mengirimkan salah satu string URL berikut dengan parameter yang dikodekan dari peramban ke server web.

  - "`https://www.foo.dom/cgi-bin/program.pl?VAR1=VAL1&VAR2=VAL2&VAR3=VAL3`"

  - "`https://www.foo.dom/cgi-bin/program.py?VAR1=VAL1&VAR2=VAL2&VAR3=VAL3`"

  - "`https://www.foo.dom/program.php?VAR1=VAL1&VAR2=VAL2&VAR3=VAL3`"

- "`%nn`" dalam URL diganti dengan sebuah karakter dengan nilai heksadesimal `nn`.

- Variabel lingkungan diatur sebagai: "`QUERY_STRING="VAR1=VAL1 VAR2=VAL2 VAR3=VAL3"`".

- Program CGI (salah satu dari "`program.*`") di server web mengeksekusi dirinya sendiri dengan variabel lingkungan "`$QUERY_STRING`".

- `stdout` program CGI dikirim ke peramban web dan disajikan sebagai halaman web dinamis interaktif.

Untuk alasan keamanan lebih baik tidak membuat hack baru untuk mengurai parameter CGI. Ada modul yang telah mapan untuk mereka di Perl dan Python. PHP hadir dengan fungsi-fungsi ini. Ketika penyimpanan data klien diperlukan, cookie HTTP digunakan. Ketika pemrosesan data sisi klien diperlukan, Javascript sering digunakan.

Untuk informasi lebih lanjut, lihat Common Gateway Interface, The Apache Software Foundation, dan JavaScript.

Mencari "tutorial CGI" di Google dengan mengetik URL yang dikodekan https://www.google.com/search?hl=en&ie=UTF-8&q=CGI+tutorial langsung ke alamat peramban adalah cara yang baik untuk melihat skrip CGI beraksi di server Google.

## 12.8. Terjemahan kode sumber

Ada program untuk mengonversi kode sumber.

Tabel 12.19. Daftar alat terjemahan kode sumber

paket | popcon | ukuran | kata kunci | deskripsi
--- | --- | --- | --- | ---
`perl` | V:673, I:992 | 836 | AWK→PERL | mengonversi kode sumber dari AWK ke PERL: a2p(1)
`f2c` | V:0.1, I:2.0 | 443 | FORTRAN→C | mengonversi kode sumber dari FORTRAN 77 ke C/C++: f2c(1)
`intel2gas` | V:0.02, I:0.19 | 178 | intel→gas | konverter dari NASM (format Intel) ke GNU Assembler (GAS)

## 12.9. Membuat paket Debian

Jika Anda ingin membuat paket Debian, baca berikut ini.

- Bab 2, Manajemen paket Debian untuk memahami sistem paket dasar

- Bagian 2.7.13, “Mem-port paket ke sistem stable” untuk memahami proses porting dasar

- Bagian 9.11.4, “Sistem chroot” untuk memahami teknik chroot dasar

- debuild(1), dan sbuild(1)

- Bagian 12.5.2, “Debugging paket Debian” untuk kompilasi ulang untuk pengawakutuan (debugging)

- Panduan untuk Pemelihara Debian (paket `debmake-doc`)

- Referensi Pengembang Debian (paket `developers-reference`)

- Manual Kebijakan Debian (paket `debian-policy`)

Ada paket seperti `debmake`, `dh-make`, `dh-make-perl`, dll., yang membantu pengemasan.

[7] Beberapa penyesuaian mungkin diperlukan untuk membuatnya bekerja di bawah sistem saat ini.

Bab 11. Konversi data |  | Lampiran A. Lampiran