.\" -*- mode: troff; coding: utf-8 -*- .\" Automatically generated by Pod::Man v6.0.2 (Pod::Simple 3.47) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. .ie n \{\ . ds C` "" . ds C' "" 'br\} .el\{\ . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Required to disable full justification in groff 1.23.0. .if n .ds AD l .\" ======================================================================== .\" .IX Title "GCOV 1" .TH GCOV 1 2026-04-30 gcc-16.1.0 GNU .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "نام (NAME)" avr-gcov \- ابزار بررسی پوشش کد آزمایشی برای برنامه‌های معماری AVR .SH "خلاصه دستور (SYNOPSIS)" .IX Header "خلاصه دستور (SYNOPSIS)" gcov [\fB\-v\fR|\fB\-\-version\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fB\-a\fR|\fB\-\-all\-blocks\fR] [\fB\-b\fR|\fB\-\-branch\-probabilities\fR] [\fB\-c\fR|\fB\-\-branch\-counts\fR] [\fB\-g\fR|\fB\-\-conditions\fR] [\fB\-e\fR|\fB\-\-prime\-paths\fR] [\fB\-\-prime\-paths\-lines[=\fR\fItype\fR\fB]\fR] [\fB\-\-prime\-paths\-source[=\fR\fItype\fR\fB]\fR] [\fB\-d\fR|\fB\-\-display\-progress\fR] [\fB\-f\fR|\fB\-\-function\-summaries\fR] [\fB\-\-include\fR \fIregex\fR] [\fB\-\-exclude\fR \fIregex\fR] [\fB\-j\fR|\fB\-\-json\-format\fR] [\fB\-H\fR|\fB\-\-human\-readable\fR] [\fB\-k\fR|\fB\-\-use\-colors\fR] [\fB\-l\fR|\fB\-\-long\-file\-names\fR] [\fB\-m\fR|\fB\-\-demangled\-names\fR] [\fB\-M\fR|\fB\-\-filter\-on\-demangled\fR] [\fB\-n\fR|\fB\-\-no\-output\fR] [\fB\-o\fR|\fB\-\-object\-directory\fR \fIdirectory|file\fR] [\fB\-p\fR|\fB\-\-preserve\-paths\fR] [\fB\-q\fR|\fB\-\-use\-hotness\-colors\fR] [\fB\-r\fR|\fB\-\-relative\-only\fR] [\fB\-s\fR|\fB\-\-source\-prefix\fR \fIdirectory\fR] [\fB\-t\fR|\fB\-\-stdout\fR] [\fB\-u\fR|\fB\-\-unconditional\-branches\fR] [\fB\-x\fR|\fB\-\-hash\-filenames\fR] \fIfiles\fR .SH "توضیحات (DESCRIPTION)" .IX Header "توضیحات (DESCRIPTION)" برنامه \&\fBgcov\fR یک برنامه آزمون پوشش کد است. از آن همراه با GCC برای تحلیل برنامه‌های خود استفاده کنید تا به ایجاد کدی کارآمدتر و با اجرای سریع‌تر کمک کرده و بخش‌های آزموده‌نشده برنامه خود را کشف نمایید. می‌توانید از \&\fBgcov\fR به عنوان یک ابزار پروفایلینگ استفاده کنید تا دریابید تلاش‌های بهینه‌سازی شما در کجای کد بیشترین تأثیر را خواهد داشت. همچنین می‌توانید از \&\fBgcov\fR همراه با ابزار پروفایلینگ دیگر، یعنی \fBgprof\fR\ ، برای ارزیابی اینکه کدام بخش‌های کد شما بیشترین میزان زمان محاسباتی را مصرف می‌کنند استفاده کنید. .PP ابزارهای پروفایلینگ به شما در تحلیل عملکرد کدتان کمک می‌کنند. با استفاده از یک پروفایلر مانند \fBgcov\fR یا \fBgprof\fR\ ، می‌توانید به برخی از آمارهای پایه عملکرد دست یابید، مانند: .IP * 4 هر خط از کد هر چند وقت یک‌بار اجرا می‌شود .IP * 4 چه خطوطی از کد در عمل اجرا می‌شوند .IP * 4 هر بخش از کد چه مقدار زمان محاسباتی مصرف می‌کند .PP هنگامی که این موارد را درباره نحوه کارکرد کد خود پس از کامپایل دانستید، می‌توانید هر ماژول را بررسی کنید تا ببینید کدام ماژول‌ها باید بهینه‌سازی شوند. \&\fBgcov\fR به شما کمک می‌کند تعیین کنید که کار بهینه‌سازی را روی کدام بخش‌ها متمرکز کنید. .PP توسعه‌دهندگان نرم‌افزار همچنین از تست پوشش کد همراه با مجموعه‌های آزمون استفاده می‌کنند تا مطمئن شوند نرم‌افزار برای انتشار واقعاً به اندازه کافی مناسب است. مجموعه‌های آزمون می‌توانند بررسی کنند که برنامه همان‌طور که انتظار می‌رود کار می‌کند؛ یک برنامه پوشش کد بررسی می‌کند که چه مقدار از برنامه توسط مجموعه آزمون اجرا شده است. سپس توسعه‌دهندگان می‌توانند مشخص کنند چه نوع مواردی باید به مجموعه‌های آزمون اضافه شوند تا هم آزمون‌های بهتری ایجاد شود و هم محصول نهایی بهتری حاصل گردد. .PP اگر قصد دارید از \&\fBgcov\fR استفاده کنید، باید کد خود را بدون بهینه‌سازی کامپایل نمایید؛ زیرا بهینه‌سازی با ترکیب چند خط کد در یک تابع، ممکن است اطلاعات کافی مورد نیاز شما را برای جستجوی «نقاط داغ» (hot spots) که در آن کد زمان زیادی از رایانه را مصرف می‌کند، ارائه ندهد. به همین ترتیب، از آنجا که \fBgcov\fR آمارها را بر پایه خط (در پایین‌ترین وضوح) جمع‌آوری می‌کند، با سبک برنامه‌نویسی‌ای بهترین کارایی را دارد که در هر خط تنها یک دستور قرار می‌گیرد. اگر از ماکروهای پیچیده‌ای استفاده کنید که به حلقه‌ها یا دیگر ساختارهای کنترلی بسط می‌یابند، آمارها کمتر مفید خواهند بود\-\-\-آن‌ها تنها در همان خطی که فراخوانی ماکرو ظاهر شده است گزارش می‌دهند. اگر ماکروهای پیچیده شما رفتاری شبیه به توابع دارند، می‌توانید برای رفع این مشکل آن‌ها را با توابع درون‌خطی (inline) جایگزین کنید. .PP برنامه \&\fBgcov\fR یک فایل لاگ به نام \fIsourcefile.gcov\fR ایجاد می‌کند که نشان می‌دهد هر خط از یک فایل منبع \fIsourcefile.c\fR چند بار اجرا شده است. می‌توانید از این فایل‌های گزارش همراه با \fBgprof\fR برای کمک به تنظیم دقیق کارایی برنامه‌های خود بهره ببرید. \fBgprof\fR اطلاعات زمان‌بندی را ارائه می‌دهد که می‌توانید همراه با اطلاعات دریافت‌شده از \&\fBgcov\fR استفاده نمایید. .PP برنامه \&\fBgcov\fR تنها روی کدهایی کار می‌کند که با GCC کامپایل شده باشند. این ابزار با هیچ سازوکار پروفایلینگ یا آزمون پوشش کد دیگری سازگار نیست. .SH "گزینه‌ها (OPTIONS)" .IX Header "گزینه‌ها (OPTIONS)" .IP \fB\-a\fR 4 .IX Item "-a" .PD 0 .IP \fB\-\-all\-blocks\fR 4 .IX Item "--all-blocks" .PD تعداد دفعات اجرای مجزا برای هر بلوک پایه را می‌نویسد. به طور معمول gcov تعداد دفعات اجرا را فقط برای بلوک‌های اصلی یک خط در خروجی می‌آورد. با این گزینه می‌توانید مشخص کنید آیا بلوک‌های درون یک خط منفرد اجرا نمی‌شوند یا خیر. .IP \fB\-b\fR 4 .IX Item "-b" .PD 0 .IP \fB\-\-branch\-probabilities\fR 4 .IX Item "--branch-probabilities" .PD بسامد انشعاب‌ها را در فایل خروجی و خلاصه اطلاعات انشعاب را در خروجی استاندارد می‌نویسد. این گزینه به شما اجازه می‌دهد ببینید هر انشعاب در برنامه شما هر چند وقت یک‌بار طی شده است. انشعاب‌های بدون شرط نشان داده نخواهند شد، مگر اینکه گزینه \fB\-u\fR داده شده باشد. .IP \fB\-c\fR 4 .IX Item "-c" .PD 0 .IP \fB\-\-branch\-counts\fR 4 .IX Item "--branch-counts" .PD بسامد انشعاب‌ها را به صورت تعداد انشعاب‌های طی‌شده می‌نویسد، نه درصد انشعاب‌های طی‌شده. .IP \fB\-g\fR 4 .IX Item "-g" .PD 0 .IP \fB\-\-conditions\fR 4 .IX Item "--conditions" .PD پوشش شرط‌ها را در فایل خروجی و اطلاعات خلاصه شرط‌ها را در خروجی استاندارد می‌نویسد. این گزینه به شما امکان می‌دهد ببینید آیا شرایط موجود در برنامه شما حداقل یک‌بار تأثیر مستقلی بر نتیجه عبارت بولی داشته‌اند یا خیر (پوشش شرط/تصمیم اصلاح‌شده یا MC/DC). این گزینه مستلزم آن است که کد منبع را با \fB\-fcondition\-coverage\fR کامپایل کنید. .IP \fB\-e\fR 4 .IX Item "-e" .PD 0 .IP \fB\-\-prime\-paths\fR 4 .IX Item "--prime-paths" .PD پوشش مسیر را در فایل خروجی و اطلاعات خلاصه مسیر را در خروجی استاندارد می‌نویسد. این گزینه به شما امکان می‌دهد ببینید چند مسیر اصلی حداقل یک بار طی شده‌اند. یک مسیر، توالی‌ای از بلوک‌های پایه است. یک مسیر در صورتی ساده است که هیچ بلوک تکراری نداشته باشد (بدون حلقه)، به جز احتمالاً اولین و آخرین بلوک، و در صورتی یک مسیر اصلی (prime path) است که مسیری ساده با حداکثر طول باشد. برای خروجی عادی، این گزینه تنها تعداد مسیرهای پوشش‌داده‌شده را شامل می‌شود. برای اطلاعات دقیق‌تر درباره مسیرها می‌توانید از \&\fB\-\-prime\-paths\-lines\fR یا \fB\-\-prime\-paths\-source\fR استفاده کنید. با \&\fB\-\-json\-format\fR تمام جزئیات مسیرها در خروجی گنجانده می‌شوند. این گزینه مستلزم آن است که کد منبع را با \fB\-fpath\-coverage\fR کامپایل کنید. .IP "\fB\-\-prime\-paths\-lines [=\fR\fItype\fR\fB]\fR" 4 .IX Item "--prime-paths-lines [=type]" پوشش مسیر را در فایل خروجی و اطلاعات خلاصه مسیر را در خروجی استاندارد می‌نویسد. این گزینه به شما امکان می‌دهد ببینید چند مسیر اصلی حداقل یک بار طی شده‌اند، و گزارش متراکمی از مسیرهای پوشش‌داده‌شده یا پوشش‌داده‌نشده و نحوه پوشش دادن آن‌ها ارائه می‌دهد. این حالت برای گزارش‌گیری خودکار و ردیابی پیشرفت مفید است. مقدار \fItype\fR می‌تواند حذف شود یا یکی از موارد زیر باشد: .RS 4 .IP * 4 \&\fIuncovered\fR \&\- شامل مسیرهای پوشش‌داده‌نشده (طی‌نشده). این حالت پیش‌فرض است. .IP * 4 \&\fIcovered\fR \&\- شامل مسیرهای پوشش‌داده‌شده (طی‌شده). .IP * 4 \&\fIboth\fR \&\- شامل تمام مسیرها. این معادل استفاده هم‌زمان از \fIcovered\fR و \&\fIuncovered\fR است. .RE .RS 4 .Sp این نمونه‌ای از خروجی \fB\-\-prime\-paths\-lines\fR است: .Sp .Vb 4 \& paths covered 12 of 15 \& path 2 not covered: lines 8 8(false) 11(true) 11 13(true) 13(true) 14 17 \& path 3 not covered: lines 8 8(false) 11(true) 11 13(true) 13(false) 16 17 \& path 4 not covered: lines 8 8(false) 11(true) 11 13(false) 16 17 .Ve .Sp این بدان معناست که برای پوشش دادن مسیر ۲ باید خطوط ۸، ۱۱، ۱۳، ۱۴ و ۱۷ را اجرا کنید، تصمیم در خط ۸ را false و تصمیم‌ها در خطوط ۱۱ و ۱۳ را \&\f(CW\*(C`false\*(C'\fR ارزیابی نمایید. .RE .IP "\fB\-\-prime\-paths\-source [=\fR\fItype\fR\fB]\fR" 4 .IX Item "--prime-paths-source [=type]" پوشش مسیر را در فایل خروجی و اطلاعات خلاصه مسیر را در خروجی استاندارد می‌نویسد. این گزینه به شما امکان می‌دهد ببینید چند مسیر اصلی حداقل یک بار طی شده‌اند، و گزارش دقیقی درباره مسیرهای پوشش‌داده‌نشده و نحوه پوشش دادن آن‌ها ارائه می‌دهد. این حالت برای درک مسیرها و تعاملات میان بخش‌های برنامه شما بسیار مفید است. مقدار \fItype\fR می‌تواند حذف شود یا یکی از موارد زیر باشد: .RS 4 .IP * 4 \&\fIuncovered\fR \&\- شامل مسیرهای پوشش‌داده‌نشده (طی‌نشده). این حالت پیش‌فرض است. .IP * 4 \&\fIcovered\fR \&\- شامل مسیرهای پوشش‌داده‌شده (طی‌شده). .IP * 4 \&\fIboth\fR \&\- شامل تمام مسیرها. این معادل استفاده هم‌زمان از \fIcovered\fR و \&\fIuncovered\fR است. .RE .RS 4 .Sp این نمونه‌ای از خروجی \fB\-\-prime\-paths\-source\fR است: .Sp .Vb 9 \& path 10 not covered: \& BB 3: 8: for (i = 0; i < 10; i++) \& BB 3: 9: total += i; \& BB 4: (false) 8: for (i = 0; i < 10; i++) \& BB 5: (true) 11: int v = total > 100 ? 1 : 2; \& BB 6: 11: int v = total > 100 ? 1 : 2; \& BB 8: (false) 13: if (total != 45 && v == 1) \& BB 11: 16: printf ("Success\en"); \& BB 12: 17: return 0; .Ve .Sp ستون اول (BB) توالی بلوک‌های پایه است (گزینه \fB\-w\fR را ببینید). ستون میانی (true/false) تصمیم مربوط به آن خط است. ستون سوم شماره خط است. ستون چهارم خود خط است. این خطوط باید به همین ترتیب اجرا شوند تا مسیر ۱۰ پوشش داده شود. .RE .IP \fB\-d\fR 4 .IX Item "-d" .PD 0 .IP \fB\-\-display\-progress\fR 4 .IX Item "--display-progress" .PD نمایش میزان پیشرفت در خروجی استاندارد. .IP \fB\-f\fR 4 .IX Item "-f" .PD 0 .IP \fB\-\-function\-summaries\fR 4 .IX Item "--function-summaries" .PD نمایش خلاصه اطلاعات برای هر تابع در خروجی، علاوه بر خلاصه در سطح فایل. .IP "\fB\-\-include\fR \fIregex\fR" 4 .IX Item "--include regex" شامل کردن توابعی که با \fIregex\fR مطابقت دارند. این گزینه باعث می‌شود \&\fBgcov\fR تنها توابعی را گزارش دهد که با عبارت باقاعده گسترش‌یافته \fIregex\fR همخوانی دارند. این فلگ می‌تواند با \&\fB\-\-exclude\fR ترکیب شود. اگر تابعی هم با include و هم با exclude مطابقت داشته باشد، آخرین مورد اعمال می‌شود. به طور پیش‌فرض \fBgcov\fR تمام توابع را گزارش می‌دهد، اما اگر \fB\-\-include\fR استفاده شود، تنها توابع منطبق با آن گزارش خواهند شد. .IP "\fB\-\-exclude\fR \fIregex\fR" 4 .IX Item "--exclude regex" مستثنی کردن توابعی که با \fIregex\fR مطابقت دارند. این گزینه باعث می‌شود \&\fBgcov\fR توابعی را که با عبارت باقاعده گسترش‌یافته \fIregex\fR همخوانی دارند گزارش نکند. این فلگ می‌تواند با \&\fB\-\-include\fR ترکیب شود. اگر تابعی هم با include و هم با exclude مطابقت داشته باشد، آخرین مورد اعمال خواهد شد. به طور پیش‌فرض \fBgcov\fR تمام توابع را گزارش می‌دهد، و اگر \fB\-\-exclude\fR استفاده شود، توابع منطبق با آن حذف خواهند شد. .IP \fB\-h\fR 4 .IX Item "-h" .PD 0 .IP \fB\-\-help\fR 4 .IX Item "--help" .PD نمایش راهنما درباره نحوه استفاده از \fBgcov\fR (در خروجی استاندارد) و خروج بدون انجام پردازش بیشتر. .IP \fB\-j\fR 4 .IX Item "-j" .PD 0 .IP \fB\-\-json\-format\fR 4 .IX Item "--json-format" .PD خروجی فایل gcov در یک قالب واسط JSON با تجزیه آسان که برای تولید نیازی به کد منبع ندارد. فایل JSON با الگوریتم فشرده‌سازی gzip فشرده شده و پسوند فایل‌ها \fI.gcov.json.gz\fR است. .Sp ساختار JSON به صورت زیر است: .Sp .Vb 7 \& { \& "current_working_directory": "foo/bar", \& "data_file": "a.out", \& "format_version": "2", \& "gcc_version": "11.1.1 20210510" \& "files": ["$file"] \& } .Ve .Sp فیلدهای عنصر ریشه دارای معانی زیر هستند: .RS 4 .IP * 4 \&\fIcurrent_working_directory\fR: پوشه کاری که واحد ترجمه در آن کامپایل شده است .IP * 4 \&\fIdata_file\fR: نام فایل داده (GCDA) .IP * 4 \&\fIformat_version\fR: نگارش معنایی قالب .Sp تغییرات در نگارش \fI2\fR: .RS 4 .IP * 4 \&\fIcalls\fR: اطلاعات مربوط به فراخوانی‌های تابع افزوده شده است .RE .RS 4 .RE .IP * 4 \&\fIgcc_version\fR: نگارش کامپایلر GCC .RE .RS 4 .Sp هر \fIfile\fR ساختار زیر را دارد: .Sp .Vb 5 \& { \& "file": "a.c", \& "functions": ["$function"], \& "lines": ["$line"] \& } .Ve .Sp فیلدهای عنصر \fIfile\fR دارای معانی زیر هستند: .IP * 4 \&\fIfile_name\fR: نام فایل منبع .RE .RS 4 .Sp هر \fIfunction\fR ساختار زیر را دارد: .Sp .Vb 11 \& { \& "blocks": 2, \& "blocks_executed": 2, \& "demangled_name": "foo", \& "end_column": 1, \& "end_line": 4, \& "execution_count": 1, \& "name": "foo", \& "start_column": 5, \& "start_line": 1 \& } .Ve .Sp فیلدهای عنصر \fIfunction\fR دارای معانی زیر هستند: .IP * 4 \&\fIblocks\fR: تعداد بلوک‌های موجود در تابع .IP * 4 \&\fIblocks_executed\fR: تعداد بلوک‌های اجراشده در تابع .IP * 4 \&\fIdemangled_name\fR: نام رمزگشایی‌شده (demangled) تابع .IP * 4 \&\fIend_column\fR: ستونی در فایل منبع که تابع در آن پایان می‌یابد .IP * 4 \&\fIend_line\fR: خطی در فایل منبع که تابع در آن پایان می‌یابد .IP * 4 \&\fIexecution_count\fR: تعداد دفعات اجرای تابع .IP * 4 \&\fIname\fR: نام تابع .IP * 4 \&\fIstart_column\fR: ستونی در فایل منبع که تابع از آن شروع می‌شود .IP * 4 \&\fIstart_line\fR: خطی در فایل منبع که تابع از آن شروع می‌شود .RE .RS 4 .Sp توجه داشته باشید که شماره خطوط و شماره ستون‌ها از ۱ آغاز می‌شوند. در پیاده‌سازی فعلی، \fIstart_line\fR و \fIstart_column\fR شامل پارامترهای قالب و نوع بازگشتی ابتدایی نیستند، اما احتمالاً در آینده اصلاح خواهد شد. .Sp هر \fIline\fR ساختار زیر را دارد: .Sp .Vb 10 \& { \& "block_ids": ["$block_id"], \& "branches": ["$branch"], \& "calls": ["$call"], \& "count": 2, \& "conditions": ["$condition"], \& "line_number": 15, \& "unexecuted_block": false, \& "function_name": "foo", \& } .Ve .Sp انشعاب‌ها و فراخوانی‌ها تنها با گزینه \fI\-b\fR حضور دارند. فیلدهای عنصر \fIline\fR دارای معانی زیر هستند: .IP * 4 \&\fIblock_ids\fR: شناسه‌های بلوک‌های پایه‌ای که به این خط تعلق دارند .IP * 4 \&\fIcount\fR: تعداد دفعات اجرای خط .IP * 4 \&\fIline_number\fR: شماره خط .IP * 4 \&\fIunexecuted_block\fR: فلگی که نشان می‌دهد آیا خط حاوی یک بلوک اجرا‌نشده است یا خیر (همه دستورات روی خط اجرا نشده‌اند) .IP * 4 \&\fIfunction_name\fR: نام تابعی که این \fIline\fR به آن تعلق دارد (برای خطی با دستورات درون‌خطی ممکن است تنظیم نشده باشد) .RE .RS 4 .Sp هر \fIbranch\fR ساختار زیر را دارد: .Sp .Vb 7 \& { \& "count": 11, \& "destination_block_id": 17, \& "fallthrough": true, \& "source_block_id": 13, \& "throw": false \& } .Ve .Sp فیلدهای عنصر \fIbranch\fR دارای معانی زیر هستند: .IP * 4 \&\fIcount\fR: تعداد دفعات اجرای انشعاب .IP * 4 \&\fIfallthrough\fR: در صورتی که انشعاب یک انشعاب عبور مستقیم (fall through) باشد true است .IP * 4 \&\fIthrow\fR: در صورتی که انشعاب یک انشعاب استثنایی باشد true است .IP * 4 \&\fIisource_block_id\fR: شناسه بلوک پایه‌ای که این انشعاب در آن رخ می‌دهد .IP * 4 \&\fIdestination_block_id\fR: شناسه بلوک پایه‌ای که این انشعاب به آن جهش می‌کند .RE .RS 4 .Sp هر \fIcall\fR ساختار زیر را دارد: .Sp .Vb 5 \& { \& "destination_block_id": 1, \& "returned": 11, \& "source_block_id": 13 \& } .Ve .Sp فیلدهای عنصر \fIcall\fR دارای معانی زیر هستند: .IP * 4 \&\fIreturned\fR: تعداد دفعاتی که یک فراخوانی تابع بازگشته است (تعداد فراخوانی برابر با \fIline::count\fR است) .IP * 4 \&\fIisource_block_id\fR: شناسه بلوک پایه‌ای که این فراخوانی در آن رخ می‌دهد .IP * 4 \&\fIdestination_block_id\fR: شناسه بلوک پایه‌ای که این فراخوانی پس از بازگشت در آن ادامه می‌یابد .RE .RS 4 .Sp هر \fIcondition\fR ساختار زیر را دارد: .Sp .Vb 6 \& { \& "count": 4, \& "covered": 2, \& "not_covered_false": [], \& "not_covered_true": [0, 1], \& } .Ve .Sp فیلدهای عنصر \fIcondition\fR دارای معانی زیر هستند: .IP * 4 \&\fIcount\fR: تعداد برآمدهای شرایط در این عبارت .IP * 4 \&\fIcovered\fR: تعداد برآمدهای پوشش‌داده‌شده شرط در این عبارت .IP * 4 \&\fInot_covered_true\fR: جملات، بر پایه اندیس، که در این عبارت به صورت true دیده نشده‌اند .IP * 4 \&\fInot_covered_false\fR: جملات، بر پایه اندیس، که در این عبارت به صورت false دیده نشده‌اند .RE .RS 4 .RE .IP \fB\-H\fR 4 .IX Item "-H" .PD 0 .IP \fB\-\-human\-readable\fR 4 .IX Item "--human-readable" .PD نوشتن تعداد دفعات در قالبی خوانا برای انسان (مانند 24.6k). .IP \fB\-k\fR 4 .IX Item "-k" .PD 0 .IP \fB\-\-use\-colors\fR 4 .IX Item "--use-colors" .PD استفاده از رنگ‌ها برای خطوط کدی که پوشش صفر دارند. از رنگ قرمز برای خطوط غیراستثنایی و رنگ فیروزه‌ای برای خطوط استثنایی استفاده می‌شود. همین رنگ‌ها برای بلوک‌های پایه با گزینه \fB\-a\fR نیز به کار می‌روند. .IP \fB\-l\fR 4 .IX Item "-l" .PD 0 .IP \fB\-\-long\-file\-names\fR 4 .IX Item "--long-file-names" .PD ایجاد نام فایل‌های طولانی برای فایل‌های منبع ضمیمه‌شده (included). برای نمونه، اگر فایل سرایند \fIx.h\fR حاوی کد باشد و در فایل \&\fIa.c\fR ضمیمه شده باشد، اجرای \fBgcov\fR روی فایل \fIa.c\fR به جای \&\fIx.h.gcov\fR\ ، یک فایل خروجی به نام \fIa.c##x.h.gcov\fR تولید می‌کند. این می‌تواند زمانی مفید باشد که \fIx.h\fR در چندین فایل منبع گنجانده شده باشد و بخواهید سهم هر یک را جداگانه مشاهده کنید. اگر از گزینه \fB\-p\fR استفاده کنید، هم نام فایل ضمیمه‌کننده و هم فایل ضمیمه‌شده به صورت مسیرهای کامل خواهند بود. .IP \fB\-m\fR 4 .IX Item "-m" .PD 0 .IP \fB\-\-demangled\-names\fR 4 .IX Item "--demangled-names" .PD نمایش نام‌های رمزگشایی‌شده (demangled) توابع در خروجی. حالت پیش‌فرض، نمایش نام‌های درهم‌ریخته (mangled) توابع است. .IP \fB\-M\fR 4 .IX Item "-M" .PD 0 .IP \fB\-\-filter\-on\-demangled\fR 4 .IX Item "--filter-on-demangled" .PD تطبیق \fB\-\-include\fR و \fB\-\-exclude\fR با نام‌های رمزگشایی‌شده (demangled). این گزینه تنها بر نحوه تطبیق اثر می‌گذارد و به معنای \&\fB\-\-demangled\-names\fR نیست، اما می‌توان آن را با اطمینان با آن ترکیب کرد. .IP \fB\-n\fR 4 .IX Item "-n" .PD 0 .IP \fB\-\-no\-output\fR 4 .IX Item "--no-output" .PD فایل خروجی \fBgcov\fR را ایجاد نمی‌کند. .IP "\fB\-o\fR \fIdirectory|file\fR" 4 .IX Item "-o directory|file" .PD 0 .IP "\fB\-\-object\-directory\fR \fIdirectory\fR" 4 .IX Item "--object-directory directory" .IP "\fB\-\-object\-file\fR \fIfile\fR" 4 .IX Item "--object-file file" .PD یا دایرکتوری حاوی فایل‌های داده gcov و یا نام مسیر شیء را مشخص می‌کند. فایل‌های داده \fI.gcno\fR و \&\fI.gcda\fR با استفاده از این گزینه جستجو می‌شوند. اگر یک دایرکتوری مشخص شود، فایل‌های داده در آن دایرکتوری قرار دارند و بر اساس نام فایل ورودی، بدون پسوند آن نام‌گذاری می‌شوند. اگر یک فایل در اینجا مشخص شود، فایل‌های داده بر اساس آن فایل، بدون پسوند آن نام‌گذاری خواهند شد. .IP \fB\-p\fR 4 .IX Item "-p" .PD 0 .IP \fB\-\-preserve\-paths\fR 4 .IX Item "--preserve-paths" .PD حفظ اطلاعات کامل مسیر در نام فایل‌های \&\fI.gcov\fR تولیدشده. بدون این گزینه، تنها بخش نام فایل استفاده می‌شود. با این گزینه، تمام دایرکتوری‌ها استفاده می‌شوند، به طوری که نویسه‌های \fB/\fR به نویسه‌های \fB#\fR تبدیل می‌شوند، بخش‌های دایرکتوری \fI.\fR حذف شده و بخش‌های غیرقابل‌حذف \fI..\fR به \fB^\fR تغییر نام می‌یابند. این در صورتی که فایل‌های منبع در چند دایرکتوری مختلف باشند مفید است. .IP \fB\-q\fR 4 .IX Item "-q" .PD 0 .IP \fB\-\-use\-hotness\-colors\fR 4 .IX Item "--use-hotness-colors" .PD تولید خروجی رنگی شبیه به perf برای خطوط داغ (پرکاربرد). راهنمای مقیاس رنگ در ابتدای فایل خروجی چاپ می‌شود. .IP \fB\-r\fR 4 .IX Item "-r" .PD 0 .IP \fB\-\-relative\-only\fR 4 .IX Item "--relative-only" .PD تنها اطلاعات مربوط به فایل‌های منبع با مسیر نسبی را در خروجی می‌آورد (پس از حذف پیشوند منبع). مسیرهای مطلق معمولاً فایل‌های سرایند سیستم هستند و پوشش توابع درون‌خطی در آن‌ها معمولاً جالب توجه نیست. .IP "\fB\-s\fR \fIdirectory\fR" 4 .IX Item "-s directory" .PD 0 .IP "\fB\-\-source\-prefix\fR \fIdirectory\fR" 4 .IX Item "--source-prefix directory" .PD پیشوندی برای نام فایل‌های منبع که هنگام تولید فایل‌های پوشش خروجی حذف شود. این گزینه زمانی مفید است که ساخت برنامه در یک پوشه جداگانه انجام می‌شود، و مسیر دایرکتوری منبع هنگام تعیین نام فایل‌های خروجی مورد نظر نیست. توجه داشته باشید که تشخیص این پیشوند قبل از تعیین مطلق بودن فایل منبع اعمال می‌شود. .IP \fB\-t\fR 4 .IX Item "-t" .PD 0 .IP \fB\-\-stdout\fR 4 .IX Item "--stdout" .PD خروجی را به جای فایل‌های خروجی به خروجی استاندارد ارسال می‌کند. .IP \fB\-u\fR 4 .IX Item "-u" .PD 0 .IP \fB\-\-unconditional\-branches\fR 4 .IX Item "--unconditional-branches" .PD هنگامی که احتمالات انشعاب داده شده است، انشعاب‌های بدون شرط را نیز لحاظ می‌کند. انشعاب‌های بدون شرط معمولاً جالب توجه نیستند. .IP \fB\-v\fR 4 .IX Item "-v" .PD 0 .IP \fB\-\-version\fR 4 .IX Item "--version" .PD نمایش شماره نگارش \fBgcov\fR (در خروجی استاندارد)، و خروج بدون انجام پردازش بیشتر. .IP \fB\-w\fR 4 .IX Item "-w" .PD 0 .IP \fB\-\-verbose\fR 4 .IX Item "--verbose" .PD چاپ اطلاعات تفصیلی مربوط به بلوک‌های پایه و کمان‌ها (arcs). .IP \fB\-x\fR 4 .IX Item "-x" .PD 0 .IP \fB\-\-hash\-filenames\fR 4 .IX Item "--hash-filenames" .PD هنگام استفاده از \fI\-\-preserve\-paths\fR\ ، ابزار gcov از نام کامل مسیر فایل‌های منبع برای ساخت نام فایل خروجی استفاده می‌کند. این امر می‌تواند به نام‌های طولانی فایل منجر شود که ممکن است از محدودیت‌های سیستم فایل فراتر رود. این گزینه نام‌هایی به فرم \&\fIsource\-file##md5.gcov\fR ایجاد می‌کند، که در آن بخش \fIsource\-file\fR بخش نهایی نام فایل است و بخش \fImd5\fR از نام کامل تغییریافته‌ای محاسبه می‌شود که در غیر این صورت استفاده می‌شد. این گزینه جایگزینی برای \fI\-\-preserve\-paths\fR در سیستم‌هایی است که دارای محدودیت سیستم فایل هستند. .PP برنامه \&\fBgcov\fR باید با دایرکتوری جاری همانند زمانی که کامپایلر را فراخوانی کرده‌اید اجرا شود. در غیر این صورت قادر به یافتن فایل‌های منبع نخواهد بود. \fBgcov\fR فایل‌هایی به نام \&\fImangledname.gcov\fR در دایرکتوری جاری تولید می‌کند. این فایل‌ها حاوی اطلاعات پوشش فایل منبع متناظر خود هستند. یک فایل \fI.gcov\fR به ازای هر فایل منبع (یا سرایند) حاوی کد تولید می‌شود که برای تولید فایل‌های داده کامپایل شده است. بخش \fImangledname\fR از نام فایل خروجی معمولاً به سادگی همان نام فایل منبع است، اما در صورت ارائه گزینه‌های \fB\-l\fR یا \fB\-p\fR می‌تواند پیچیده‌تر باشد. برای جزئیات بیشتر به توضیحات آن گزینه‌ها مراجعه کنید. .PP اگر \fBgcov\fR را با چندین فایل ورودی فراخوانی کنید، سهم هر فایل ورودی جمع زده می‌شود. معمولاً شما آن را با همان فهرست فایل‌هایی فراخوانی می‌کنید که در پیوند نهایی برنامه اجرایی خود استفاده کرده‌اید. .PP فایل‌های \fI.gcov\fR شامل فیلدهایی هستند که با \fB:\fR همراه با کد منبع برنامه جدا شده‌اند. قالب آن به صورت زیر است: .PP .Vb 1 \& :: .Ve .PP در صورت درخواست از طریق گزینه خط فرمان، ممکن است اطلاعات بلوک اضافی پس از هر خط بیاید. مقدار \fIexecution_count\fR برای خطوط فاقد کد \fB\-\fR است. خطوط اجرا نشده بسته به اینکه از طریق مسیرهای غیراستثنایی قابل دسترس باشند یا تنها از طریق مسیرهای استثنایی مانند گرداننده‌های استثنای ++C، به ترتیب با \fB#####\fR یا \&\fB=====\fR مشخص می‌شوند. در صورت ارائه گزینه \fB\-a\fR\ ، بلوک‌های اجرا نشده بسته به اینکه یک بلوک پایه از طریق مسیرهای غیراستثنایی یا استثنایی قابل دسترس باشد با \fB$$$$$\fR یا \fB%%%%%\fR مشخص می‌گردند. بلوک‌های پایه اجرا شده که دارای دستوری با \fIexecution_count\fR صفر هستند، با نویسه \fB*\fR خاتمه می‌یابند و با گزینه \fB\-k\fR به رنگ سرخابی (magenta) نشان داده می‌شوند. این قابلیت در Ada پشتیبانی نمی‌شود. .PP توجه داشته باشید که GCC می‌تواند بدنه توابعی را که مورد نیاز نیستند کاملاً حذف کند \-\- برای مثال اگر در همه‌جا درون‌خطی (inline) شده باشند. چنین توابعی با \fB\-\fR مشخص می‌شوند که می‌تواند گیج‌کننده باشد. از گزینه‌های \fB\-fkeep\-inline\-functions\fR و \fB\-fkeep\-static\-functions\fR برای حفظ این توابع استفاده کنید تا به gcov اجازه دهد \fIexecution_count\fR آن‌ها را به درستی نمایش دهد. .PP برخی از خطوط اطلاعاتی در ابتدا دارای \fIline_number\fR صفر هستند. این خطوط مقدماتی به فرم زیر هستند: .PP .Vb 1 \& \-:0:: .Ve .PP ترتیب و تعداد این خطوط مقدماتی همگام با پیشرفت توسعه \&\fBgcov\fR افزایش خواهد یافت \-\-\- به بدون تغییر ماندن آن‌ها اتکا نکنید. از \fItag\fR برای یافتن یک خط مقدماتی خاص استفاده کنید. .PP اطلاعات بلوک اضافی به فرم زیر است: .PP .Vb 1 \& .Ve .PP بخش \fIinformation\fR برای انسان خوانا است، اما طوری طراحی شده است که برای تجزیه ماشینی نیز به اندازه کافی ساده باشد. .PP هنگام چاپ درصدها، 0% و 100% تنها زمانی چاپ می‌شوند که مقادیر به ترتیب \fIدقیقاً\fR 0% و 100% باشند. سایر مقادیری که به طور سنتی به 0% یا 100% گرد می‌شوند، در عوض به عنوان نزدیک‌ترین مقدار غیرمرزی چاپ می‌شوند. .PP هنگام استفاده از \fBgcov\fR\ ، ابتدا باید برنامه خود را با یک گزینه ویژه GCC به نام \fB\-\-coverage\fR کامپایل کنید. این به کامپایلر اعلام می‌کند اطلاعات اضافی مورد نیاز gcov (اساساً یک گراف جریان از برنامه) را تولید کند و همچنین کدهای اضافی را در فایل‌های شیء جهت تولید اطلاعات پروفایلینگ اضافی مورد نیاز gcov بگنجاند. این فایل‌های اضافی در دایرکتوری محل قرارگیری فایل شیء قرار داده می‌شوند. .PP اجرای برنامه باعث تولید خروجی پروفایل خواهد شد. برای هر فایل منبع کامپایل‌شده با \fB\-fprofile\-arcs\fR\ ، یک فایل \&\fI.gcda\fR همراه در دایرکتوری فایل شیء قرار خواهد گرفت. .PP اکنون اجرای \fBgcov\fR با نام فایل‌های منبع برنامه شما به عنوان آرگومان، فهرستی از کد را همراه با بسامد اجرای هر خط تولید می‌کند. برای نمونه، اگر برنامه شما \fItmp.cpp\fR نام دارد، هنگام استفاده از قابلیت‌های پایه \fBgcov\fR این چیزی است که می‌بینید: .PP .Vb 7 \& $ g++ \-\-coverage tmp.cpp \-c \& $ g++ \-\-coverage tmp.o \& $ a.out \& $ gcov tmp.cpp \-m \& File \*(Aqtmp.cpp\*(Aq \& Lines executed:92.86% of 14 \& Creating \*(Aqtmp.cpp.gcov\*(Aq .Ve .PP فایل \fItmp.cpp.gcov\fR حاوی خروجی \fBgcov\fR است. در اینجا یک نمونه آورده شده است: .PP .Vb 10 \& \-: 0:Source:tmp.cpp \& \-: 0:Working directory:/home/gcc/testcase \& \-: 0:Graph:tmp.gcno \& \-: 0:Data:tmp.gcda \& \-: 0:Runs:1 \& \-: 0:Programs:1 \& \-: 1:#include \& \-: 2: \& \-: 3:template \& \-: 4:class Foo \& \-: 5:{ \& \-: 6: public: \& 1*: 7: Foo(): b (1000) {} \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& Foo::Foo(): \& #####: 7: Foo(): b (1000) {} \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& Foo::Foo(): \& 1: 7: Foo(): b (1000) {} \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& 2*: 8: void inc () { b++; } \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& Foo::inc(): \& #####: 8: void inc () { b++; } \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& Foo::inc(): \& 2: 8: void inc () { b++; } \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& \-: 9: \& \-: 10: private: \& \-: 11: int b; \& \-: 12:}; \& \-: 13: \& \-: 14:template class Foo; \& \-: 15:template class Foo; \& \-: 16: \& \-: 17:int \& 1: 18:main (void) \& \-: 19:{ \& \-: 20: int i, total; \& 1: 21: Foo counter; \& \-: 22: \& 1: 23: counter.inc(); \& 1: 24: counter.inc(); \& 1: 25: total = 0; \& \-: 26: \& 11: 27: for (i = 0; i < 10; i++) \& 10: 28: total += i; \& \-: 29: \& 1*: 30: int v = total > 100 ? 1 : 2; \& \-: 31: \& 1: 32: if (total != 45) \& #####: 33: printf ("Failure\en"); \& \-: 34: else \& 1: 35: printf ("Success\en"); \& 1: 36: return 0; \& \-: 37:} .Ve .PP توجه داشته باشید که خط ۷ در گزارش چندین بار نشان داده شده است. اولین رخداد، تعداد کل دفعات اجرای خط را ارائه می‌دهد و دو مورد بعدی متعلق به نمونه‌های سازنده‌های کلاس Foo هستند. همان‌طور که می‌بینید، خط ۳۰ حاوی برخی بلوک‌های پایه اجرا نشده است و بنابراین تعداد دفعات اجرای آن دارای نماد ستاره است. .PP هنگامی که از گزینه \fB\-a\fR استفاده می‌کنید، شمارش‌های بلوک‌های مجزا را دریافت خواهید کرد و خروجی شبیه به این خواهد بود: .PP .Vb 10 \& \-: 0:Source:tmp.cpp \& \-: 0:Working directory:/home/gcc/testcase \& \-: 0:Graph:tmp.gcno \& \-: 0:Data:tmp.gcda \& \-: 0:Runs:1 \& \-: 0:Programs:1 \& \-: 1:#include \& \-: 2: \& \-: 3:template \& \-: 4:class Foo \& \-: 5:{ \& \-: 6: public: \& 1*: 7: Foo(): b (1000) {} \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& Foo::Foo(): \& #####: 7: Foo(): b (1000) {} \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& Foo::Foo(): \& 1: 7: Foo(): b (1000) {} \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& 2*: 8: void inc () { b++; } \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& Foo::inc(): \& #####: 8: void inc () { b++; } \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& Foo::inc(): \& 2: 8: void inc () { b++; } \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& \-: 9: \& \-: 10: private: \& \-: 11: int b; \& \-: 12:}; \& \-: 13: \& \-: 14:template class Foo; \& \-: 15:template class Foo; \& \-: 16: \& \-: 17:int \& 1: 18:main (void) \& \-: 19:{ \& \-: 20: int i, total; \& 1: 21: Foo counter; \& 1: 21\-block 0 \& \-: 22: \& 1: 23: counter.inc(); \& 1: 23\-block 0 \& 1: 24: counter.inc(); \& 1: 24\-block 0 \& 1: 25: total = 0; \& \-: 26: \& 11: 27: for (i = 0; i < 10; i++) \& 1: 27\-block 0 \& 11: 27\-block 1 \& 10: 28: total += i; \& 10: 28\-block 0 \& \-: 29: \& 1*: 30: int v = total > 100 ? 1 : 2; \& 1: 30\-block 0 \& %%%%%: 30\-block 1 \& 1: 30\-block 2 \& \-: 31: \& 1: 32: if (total != 45) \& 1: 32\-block 0 \& #####: 33: printf ("Failure\en"); \& %%%%%: 33\-block 0 \& \-: 34: else \& 1: 35: printf ("Success\en"); \& 1: 35\-block 0 \& 1: 36: return 0; \& 1: 36\-block 0 \& \-: 37:} .Ve .PP در این حالت، هر بلوک پایه تنها در یک خط نشان داده می‌شود \-\- آخرین خط بلوک. یک بلوک چندخطی تنها به تعداد دفعات اجرای آن خط آخر کمک می‌کند، و خطوط دیگر فاقد کد نشان داده می‌شوند، مگر اینکه بلوک‌های قبلی در آن خطوط پایان یابند. تعداد کل دفعات اجرای یک خط نشان داده می‌شود و خطوط بعدی تعداد دفعات اجرا را برای تک‌تک بلوک‌هایی که در آن خط پایان می‌یابند نمایش می‌دهند. پس از هر بلوک، در صورت ارائه گزینه \&\fB\-b\fR\ ، تعداد انشعاب‌ها و فراخوانی‌های آن بلوک نمایش داده خواهد شد. .PP به دلیل روشی که GCC فراخوانی‌ها را ابزارگذاری (instrument) می‌کند، تعداد فراخوانی می‌تواند پس از خطی بدون بلوک‌های مجزا نشان داده شود. همان‌طور که می‌بینید، خط ۳۳ حاوی یک بلوک پایه است که اجرا نشده است. .PP هنگامی که از گزینه \fB\-b\fR استفاده می‌کنید، خروجی شما شبیه به این خواهد بود: .PP .Vb 10 \& \-: 0:Source:tmp.cpp \& \-: 0:Working directory:/home/gcc/testcase \& \-: 0:Graph:tmp.gcno \& \-: 0:Data:tmp.gcda \& \-: 0:Runs:1 \& \-: 0:Programs:1 \& \-: 1:#include \& \-: 2: \& \-: 3:template \& \-: 4:class Foo \& \-: 5:{ \& \-: 6: public: \& 1*: 7: Foo(): b (1000) {} \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& Foo::Foo(): \& function Foo::Foo() called 0 returned 0% blocks executed 0% \& #####: 7: Foo(): b (1000) {} \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& Foo::Foo(): \& function Foo::Foo() called 1 returned 100% blocks executed 100% \& 1: 7: Foo(): b (1000) {} \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& 2*: 8: void inc () { b++; } \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& Foo::inc(): \& function Foo::inc() called 0 returned 0% blocks executed 0% \& #####: 8: void inc () { b++; } \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& Foo::inc(): \& function Foo::inc() called 2 returned 100% blocks executed 100% \& 2: 8: void inc () { b++; } \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& \-: 9: \& \-: 10: private: \& \-: 11: int b; \& \-: 12:}; \& \-: 13: \& \-: 14:template class Foo; \& \-: 15:template class Foo; \& \-: 16: \& \-: 17:int \& function main called 1 returned 100% blocks executed 81% \& 1: 18:main (void) \& \-: 19:{ \& \-: 20: int i, total; \& 1: 21: Foo counter; \& call 0 returned 100% \& branch 1 taken 100% (fallthrough) \& branch 2 taken 0% (throw) \& \-: 22: \& 1: 23: counter.inc(); \& call 0 returned 100% \& branch 1 taken 100% (fallthrough) \& branch 2 taken 0% (throw) \& 1: 24: counter.inc(); \& call 0 returned 100% \& branch 1 taken 100% (fallthrough) \& branch 2 taken 0% (throw) \& 1: 25: total = 0; \& \-: 26: \& 11: 27: for (i = 0; i < 10; i++) \& branch 0 taken 91% (fallthrough) \& branch 1 taken 9% \& 10: 28: total += i; \& \-: 29: \& 1*: 30: int v = total > 100 ? 1 : 2; \& branch 0 taken 0% (fallthrough) \& branch 1 taken 100% \& \-: 31: \& 1: 32: if (total != 45) \& branch 0 taken 0% (fallthrough) \& branch 1 taken 100% \& #####: 33: printf ("Failure\en"); \& call 0 never executed \& branch 1 never executed \& branch 2 never executed \& \-: 34: else \& 1: 35: printf ("Success\en"); \& call 0 returned 100% \& branch 1 taken 100% (fallthrough) \& branch 2 taken 0% (throw) \& 1: 36: return 0; \& \-: 37:} .Ve .PP برای هر تابع، خطی چاپ می‌شود که نشان می‌دهد تابع چند بار فراخوانی شده، چند بار بازگشته و چه درصدی از بلوک‌های تابع اجرا شده‌اند. .PP برای هر بلوک پایه، خطی پس از آخرین خط بلوک پایه چاپ می‌شود که انشعاب یا فراخوانی پایان‌دهنده بلوک پایه را توصیف می‌کند. اگر چندین بلوک پایه در یک خط پایان یابند، می‌تواند چندین انشعاب و فراخوانی برای یک خط منبع فهرست شود. در این حالت، به هر یک از انشعاب‌ها و فراخوانی‌ها یک شماره اختصاص داده می‌شود. راه ساده‌ای برای نگاشت این انشعاب‌ها و فراخوانی‌ها به ساختارهای کد منبع وجود ندارد. با این حال، به طور کلی، کمترین شماره انشعاب یا فراخوانی با چپ‌ترین ساختار روی خط منبع متناظر خواهد بود. .PP برای یک انشعاب، اگر حداقل یک بار اجرا شده باشد، درصدی چاپ می‌شود که نشان‌دهنده تعداد دفعات طی‌شدن انشعاب تقسیم بر تعداد دفعات اجرای انشعاب است. در غیر این صورت، پیام "never executed" چاپ می‌شود. .PP برای یک فراخوانی، اگر حداقل یک بار اجرا شده باشد، درصدی چاپ می‌شود که نشان‌دهنده تعداد دفعات بازگشت فراخوانی تقسیم بر تعداد دفعات اجرای فراخوانی است. این مقدار معمولاً 100% خواهد بود، اما ممکن است برای توابعی که \f(CW\*(C`exit\*(C'\fR یا \f(CW\*(C`longjmp\*(C'\fR را فراخوانی می‌کنند کمتر باشد، زیرا ممکن است در هر بار فراخوانی بازنگردند. .PP هنگامی که از گزینه \fB\-g\fR استفاده می‌کنید، خروجی شما شبیه به این خواهد بود: .PP .Vb 10 \& $ gcov \-t \-m \-g tmp \& \-: 0:Source:tmp.cpp \& \-: 0:Graph:tmp.gcno \& \-: 0:Data:tmp.gcda \& \-: 0:Runs:1 \& \-: 1:#include \& \-: 2: \& \-: 3:int \& 1: 4:main (void) \& \-: 5:{ \& \-: 6: int i, total; \& 1: 7: total = 0; \& \-: 8: \& 11: 9: for (i = 0; i < 10; i++) \& condition outcomes covered 2/2 \& 10: 10: total += i; \& \-: 11: \& 1*: 12: int v = total > 100 ? 1 : 2; \& condition outcomes covered 1/2 \& condition 0 not covered (true) \& \-: 13: \& 1*: 14: if (total != 45 && v == 1) \& condition outcomes covered 1/4 \& condition 0 not covered (true) \& condition 1 not covered (true false) \& #####: 15: printf ("Failure\en"); \& \-: 16: else \& 1: 17: printf ("Success\en"); \& 1: 18: return 0; \& \-: 19:} .Ve .PP برای هر شرط، تعداد برآمدهای طی‌شده و برآمدهای کل چاپ می‌شود، و در صورتی که برآمدهای پوشش‌داده‌نشده‌ای وجود داشته باشد، خطی برای هر شرط چاپ می‌شود که برآمد پوشش‌داده‌نشده را درون پرانتز نشان می‌دهد. شرایط با اندیس خود مشخص می‌شوند \-\- اندیس ۰ چپ‌ترین شرط است. در \f(CW\*(C`a || (b && c)\*(C'\fR\ ، بخش \fIa\fR شرط ۰، بخش \fIb\fR شرط ۱، و \fIc\fR شرط ۲ است. .PP یک برآمد در صورتی پوشش‌داده‌شده تلقی می‌شود که تأثیر مستقلی بر تصمیم داشته باشد، که به عنوان MC/DC ماسک‌شده (پوشش شرط/تصمیم اصلاح‌شده) نیز شناخته می‌شود. در این مثال، تصمیم به true ارزیابی می‌شود و \fIa\fR ارزیابی می‌گردد، اما پوشش داده نمی‌شود. این به این دلیل است که \fIa\fR نمی‌تواند به طور مستقل بر تصمیم تأثیر بگذارد \-\- برای تغییر تصمیم، باید هر دو \fIa\fR و \fIb\fR تغییر مقدار دهند. .PP .Vb 10 \& $ gcov \-t \-m \-g tmp \& \-: 0:Source:tmp.c \& \-: 0:Graph:tmp.gcno \& \-: 0:Data:tmp.gcda \& \-: 0:Runs:1 \& \-: 1:#include \& \-: 2: \& 1: 3:int main() \& \-: 4:{ \& 1: 5: int a = 1; \& 1: 6: int b = 0; \& \-: 7: \& 1: 8: if (a && b) \& condition outcomes covered 1/4 \& condition 0 not covered (true false) \& condition 1 not covered (true) \& #####: 9: printf ("Success!\en"); \& \-: 10: else \& 1: 11: printf ("Failure!\en"); \& \-: 12:} .Ve .PP هنگامی که با \fB\-\-coverage \-fpath\-coverage\fR کامپایل کرده و از گزینه \fB\-e\fR استفاده می‌کنید، خروجی شما شبیه به این خواهد بود: .PP .Vb 10 \& $ gcov \-t \-e tmp \& \-: 0:Source:tmp.cpp \& \-: 0:Graph:tmp.gcno \& \-: 0:Data:tmp.gcda \& \-: 0:Runs:1 \& \-: 1:#include \& \-: 2: \& paths covered 4 of 15 \& 1: 3:int main () \& \-: 4:{ \& \-: 5: int i, total; \& 1: 6: total = 0; \& \-: 7: \& 11: 8: for (i = 0; i < 10; i++) \& 10: 9: total += i; \& \-: 10: \& 1*: 11: int v = total > 100 ? 1 : 2; \& \-: 12: \& 1*: 13: if (total != 45 && v == 1) \& #####: 14: printf ("Failure\en"); \& \-: 15: else \& 1: 16: printf ("Success\en"); \& 1: 17: return 0; \& \-: 18:} .Ve .PP این خروجی برای درک تقریبی اینکه پوشش در کجا از دست رفته است و آزمایش اینکه چگونه ورودی‌های مختلف پوشش را تغییر می‌دهند مفید است. گزینه \&\fB\-\-prime\-paths\-source\fR ابزاری مفید برای درک مسیرها است. .PP .Vb 10 \& $ gcov \-t \-\-prime\-paths\-source tmp \& \-: 0:Source:tmp.cpp \& \-: 0:Graph:tmp.gcno \& \-: 0:Data:tmp.gcda \& \-: 0:Runs:1 \& \-: 1:#include \& \-: 2: \& paths covered 4 of 15 \& path 1: \& BB 2: 3:int main () \& BB 2: 6: total = 0; \& BB 2: 8: for (i = 0; i < 10; i++) \& BB 4: (false) 8: for (i = 0; i < 10; i++) \& BB 5: (true) 11: int v = total > 100 ? 1 : 2; \& BB 6: 11: int v = total > 100 ? 1 : 2; \& BB 8: (true) 13: if (total != 45 && v == 1) \& BB 9: (true) 13: if (total != 45 && v == 1) \& BB 10: 14: printf ("Failure\en"); \& BB 12: 17: return 0; .Ve .PP در این حالت، gcov جزئیات مربوط به مسیرهای گم‌شده را چاپ می‌کند. ستون اول توالی بلوک‌های پایه (BB) را فهرست می‌کند. ستون دوم تصمیمی است که باید در آن خط گرفته شود، در صورتی که وجود داشته باشد. ستون‌های پایانی شماره خط و خود خط هستند. این برای درک مسیرها، به ویژه مسیرهایی که پوشش آن‌ها دشوار یا حتی غیرقابل دسترسی است، مفید می‌باشد. خطوط ممکن است تکرار شوند، برای مثال در حلقه \f(CW\*(C`for\*(C'\fR\ ، اگر همان خط بخشی از چندین بلوک پایه باشد. این حالت برای انسان‌ها در نظر گرفته شده و برای درک اینکه چه کدی تحت آزمایش یا برای ورودی‌های داده‌شده اجرا می‌شود مناسب است. این خروجی کاملاً مفصل است، و برای تمرکز روی توابع خاص می‌توان آن را با فیلترهای \&\fB\-\-include\fR و \fB\-\-exclude\fR ترکیب کرد. .PP خروجی متراکم‌تری با \fB\-\-prime\-paths\-lines\fR در دسترس است که شبیه به این است: .PP .Vb 10 \& \-: 0:Source:tmp.cpp \& \-: 0:Graph:tmp.gcno \& \-: 0:Data:tmp.gcda \& \-: 0:Runs:1 \& \-: 1:#include \& \-: 2: \& paths covered 4 of 15 \& path 1 not covered: lines 8 8(false) 11(true) 11 13(true) 13(true) 14 17 \& path 2 not covered: lines 8 8(false) 11(true) 11 13(true) 13(false) 16 17 \& path 3 not covered: lines 8 8(false) 11(true) 11 13(false) 16 17 \& path 4 not covered: lines 8 8(false) 11(false) 11 13(true) 13(true) 14 17 \& path 5 not covered: lines 8 8(false) 11(false) 11 13(true) 13(false) 16 17 \& path 6 not covered: lines 8 8(false) 11(false) 11 13(false) 16 17 \& path 8 not covered: lines 9 8(false) 11(true) 11 13(true) 13(true) 14 17 \& path 9 not covered: lines 9 8(false) 11(true) 11 13(true) 13(false) 16 17 \& path 10 not covered: lines 9 8(false) 11(true) 11 13(false) 16 17 \& path 11 not covered: lines 9 8(false) 11(false) 11 13(true) 13(true) 14 17 \& path 12 not covered: lines 9 8(false) 11(false) 11 13(true) 13(false) 16 17 \& 1: 3:int main () \& \-: 4:{ .Ve .PP در این حالت، هر مسیر گم‌شده با استفاده از خطوط و تصمیمات مانند \fB\-\-prime\-paths\-source\fR اما در یک خط منفرد باز می‌شود. این حالت دید کلی مناسبی روی مسیرها و برای ردیابی نحوه آزموده شدن کد توسط آزمون‌ها و ورودی‌های مختلف فراهم می‌سازد. .PP تعداد دفعات اجرا تجمعی هستند. اگر برنامه نمونه دوباره بدون حذف فایل \fI.gcda\fR اجرا شود، تعداد دفعات اجرای هر خط در کد منبع به نتایج اجرای (یا اجراهای) قبلی افزوده خواهد شد. این امر از چندین جهت می‌تواند مفید باشد. برای نمونه، می‌تواند برای جمع‌آوری داده‌ها در طول چندین بار اجرای برنامه به عنوان بخشی از یک مجموعه اعتبارسنجی آزمون، یا برای ارائه اطلاعات دقیق‌تر بلندمدت در طول تعداد زیادی از اجراهای برنامه به کار رود. .PP داده‌های موجود در فایل‌های \fI.gcda\fR درست پیش از خروج برنامه ذخیره می‌شوند. برای هر فایل منبع کامپایل‌شده با \fB\-fprofile\-arcs\fR\ ، کد پروفایلینگ ابتدا تلاش می‌کند یک فایل \fI.gcda\fR موجود را بخواند؛ اگر فایل با فایل اجرایی مطابقت نداشته باشد (تعداد متفاوتی از شمارش‌های بلوک پایه)، محتوای فایل را نادیده می‌گیرد. سپس تعداد دفعات اجرای جدید را اضافه کرده و در نهایت داده‌ها را در فایل می‌نویسد. .PP می‌توانید با استفاده از \fB\-\-include\fR و \fB\-\-exclude\fR گزارشی از زیرمجموعه‌ای از توابع تهیه کنید. این کار هنگام ترکیب با \&\fB\-\-stdout\fR جهت تلاش برای درک رفتار و پوشش یک تابع خاص با اجرای یک آزمون، بررسی خروجی \fBgcov\fR\ ، آزمایش ورودی دیگر و اجرای مجدد \fBgcov\fR بسیار سودمند است. .PP .Vb 10 \& $ gcov \-m \-\-stdout \-\-include inc tmp \& \-: 0:Source:tmp.cpp \& \-: 0:Graph:tmp.gcno \& \-: 0:Data:tmp.gcda \& \-: 0:Runs:1 \& 2*: 8: void inc () { b++; } \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& Foo::inc(): \& #####: 8: void inc () { b++; } \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& Foo::inc(): \& 2: 8: void inc () { b++; } \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- .Ve .PP ابزار \&\fBgcov\fR به طور پیش‌فرض روی نام‌های درهم‌ریخته (mangled) مطابقت می‌دهد، که می‌توانید با پرچم \fB\-M\fR آن را کنترل کنید. توجه داشته باشید که تطبیق و گزارش‌دهی مستقل هستند، بنابراین می‌توانید روی نام‌های درهم‌ریخته مطابقت دهید در حالی که نام‌های رمزگشایی‌شده (demangled) را چاپ می‌کنید، و برعکس. برای گزارش‌گیری از نمونه‌سازی \f(CW\*(C`int\*(C'\fR از \f(CW\*(C`Foo\*(C'\fR با تطبیق روی نام‌های mangled و demangled: .PP .Vb 7 \& $ gcov \-t \-m \-M tmp \-\-include \*(AqFoo\*(Aq \& \-: 0:Source:tmp.cpp \& \-: 0:Graph:tmp.gcno \& \-: 0:Data:tmp.gcda \& \-: 0:Runs:1 \& 1: 7: Foo(): b (1000) {} \& 2: 8: void inc () { b++; } \& \& \& \& $ gcov \-t \-m tmp \-\-include \*(AqFooIi\*(Aq \& \-: 0:Source:tmp.cpp \& \-: 0:Graph:tmp.gcno \& \-: 0:Data:tmp.gcda \& \-: 0:Runs:1 \& 1: 7: Foo(): b (1000) {} \& 2: 8: void inc () { b++; } .Ve .PP آرگومان‌های \fB\-\-include\fR و \fB\-\-exclude\fR عبارت‌های باقاعده گسترش‌یافته هستند (مانند \fBgrep \-E\fR\ )، بنابراین الگوی \&\f(CW\*(C`in.?\*(C'\fR هم با \f(CW\*(C`inc\*(C'\fR و هم با \f(CW\*(C`main\*(C'\fR مطابقت دارد. اگر همراه با \&\fB\-M\fR استفاده شود، تمام نمونه‌سازی‌های \f(CW\*(C`int\*(C'\fR از \f(CW\*(C`Foo\*(C'\fR نیز تطبیق داده می‌شوند. \fB\-\-include\fR و \fB\-\-exclude\fR می‌توانند چندین بار استفاده شوند، و اگر نامی با چندین فیلتر مطابقت داشته باشد، آخرین موردی که همخوانی دارد اولویت خواهد داشت. برای نمونه، جهت تطبیق \&\f(CW\*(C`main\*(C'\fR و نمونه‌سازی \f(CW\*(C`int\*(C'\fR از \f(CW\*(C`inc\*(C'\fR\ ، ضمن حذف سازنده \f(CW\*(C`Foo\*(C'\fR\ : .PP .Vb 10 \& $ gcov \-t \-m \-M \-\-include in \-\-exclude Foo \-\-include \*(Aq::inc\*(Aq tmp \& \-: 0:Source:tmp.cpp \& \-: 0:Graph:tmp.gcno \& \-: 0:Data:tmp.gcda \& \-: 0:Runs:1 \& 2: 8: void inc () { b++; } \& 1: 18:main (void) \& \-: 19:{ \& \-: 20: int i, total; \& 1: 21: Foo counter; \& \-: 22: \& 1: 23: counter.inc(); \& 1: 24: counter.inc(); \& 1: 25: total = 0; \& \-: 26: \& 11: 27: for (i = 0; i < 10; i++) \& 10: 28: total += i; \& \-: 29: \& 1*: 30: int v = total > 100 ? 1 : 2; \& \-: 31: \& 1: 32: if (total != 45) \& #####: 33: printf ("Failure\en"); \& \-: 34: else \& 1: 35: printf ("Success\en"); \& 1: 36: return 0; \& \-: 37:} .Ve .SS "استفاده از \fBgcov\fP با بهینه‌سازی GCC" .IX Subsection "Using gcov with GCC Optimization" اگر قصد دارید از \fBgcov\fR برای کمک به بهینه‌سازی کد خود استفاده کنید، ابتدا باید برنامه خود را با یک گزینه ویژه GCC یعنی \&\fB\-\-coverage\fR کامپایل نمایید. علاوه بر آن، می‌توانید از هر گزینه دیگر GCC نیز استفاده کنید؛ اما اگر می‌خواهید اثبات نمایید که تک‌تک خطوط برنامه شما اجرا شده‌اند، نباید هم‌زمان با بهینه‌سازی کامپایل کنید. در برخی ماشین‌ها، بهینه‌ساز می‌تواند با ادغام خطوط کد ساده با خطوط دیگر، برخی خطوط را حذف کند. برای مثال، کدی مانند این: .PP .Vb 4 \& if (a != b) \& c = 1; \& else \& c = 0; .Ve .PP در برخی ماشین‌ها می‌تواند در قالب یک دستورالعمل ماشین کامپایل شود. در این حالت، هیچ راهی برای \fBgcov\fR وجود ندارد که تعداد دفعات اجرای جداگانه برای هر خط را محاسبه کند، زیرا کد مجزایی برای هر خط وجود ندارد. از این رو در صورت کامپایل برنامه با بهینه‌سازی، خروجی \fBgcov\fR شبیه به این خواهد بود: .PP .Vb 4 \& 100: 12:if (a != b) \& 100: 13: c = 1; \& 100: 14:else \& 100: 15: c = 0; .Ve .PP خروجی نشان می‌دهد این بلوک کد که با بهینه‌سازی ترکیب شده است، ۱۰۰ بار اجرا شده است. از یک دیدگاه این نتیجه درست است، زیرا تنها یک دستورالعمل ماشین نشان‌دهنده تمام این چهار خط بوده است. با این حال، خروجی مشخص نمی‌کند که نتیجه چند بار ۰ و چند بار ۱ بوده است. .PP توابع قابل درون‌خطی‌سازی (inlineable) می‌توانند تعداد خطوط غیرمنتظره‌ای ایجاد کنند. شمارش خطوط برای کد منبع تابع قابل درون‌خطی‌سازی نشان داده می‌شود، اما آنچه نشان داده می‌شود به این بستگی دارد که تابع در کجا درون‌خطی شده باشد، یا اینکه اصلاً درون‌خطی نشده باشد. .PP اگر تابع درون‌خطی نشود، کامپایلر باید یک کپی خارج از خط (out of line) از تابع را در هر فایل شیئی که به آن نیاز دارد تولید کند. اگر \&\fIfileA.o\fR و \fIfileB.o\fR هر دو حاوی بدنه‌های خارج از خط یک تابع درون‌خطی‌پذیر خاص باشند، هر دو نیز حاوی شمارش‌های پوشش برای آن تابع خواهند بود. هنگامی که \fIfileA.o\fR و \fIfileB.o\fR با هم پیوند داده می‌شوند، پیونددهنده در بسیاری از سیستم‌ها یکی از آن بدنه‌های خارج از خط را برای تمام فراخوانی‌های آن تابع انتخاب کرده و دیگری را حذف یا نادیده می‌گیرد. متأسفانه، شمارنده‌های پوشش را برای بدنه استفاده‌نشده تابع حذف نخواهد کرد. از این رو هنگام ابزارگذاری، همه به جز یکی از کاربردهای آن تابع، شمارش صفر را نشان خواهند داد. .PP اگر تابع در چندین مکان درون‌خطی شود، ساختار بلوک در هر مکان ممکن است یکسان نباشد. برای مثال، ممکن است یک شرط اکنون در برخی موارد در زمان کامپایل قابل محاسبه باشد. از آنجا که پوشش تمام استفاده‌های تابع درون‌خطی برای همان خطوط منبع نمایش داده خواهد شد، خود شمارش خطوط ممکن است متناقض به نظر برسند. .PP برنامه‌های با اجرای طولانی می‌توانند از امکانات \f(CW\*(C`_\|_gcov_reset\*(C'\fR و \f(CW\*(C`_\|_gcov_dump\*(C'\fR برای محدود کردن جمع‌آوری پروفایل به ناحیه مورد نظر برنامه استفاده نمایند. فراخوانی \f(CW\*(C`_\|_gcov_reset(void)\*(C'\fR تمام شمارنده‌های پروفایل زمان اجرا را صفر می‌کند، و فراخوانی \f(CW\*(C`_\|_gcov_dump(void)\*(C'\fR باعث می‌شود اطلاعات پروفایل جمع‌آوری‌شده در آن نقطه در فایل‌های خروجی \fI.gcda\fR تخلیه شوند. برنامه‌های ابزارگذاری‌شده از یک تخریب‌کننده استاتیک با اولویت ۹۹ برای فراخوانی تابع \f(CW\*(C`_\|_gcov_dump\*(C'\fR استفاده می‌کنند. بنابراین \f(CW\*(C`_\|_gcov_dump\*(C'\fR پس از تمام تخریب‌کننده‌های استاتیک تعریف‌شده توسط کاربر، و همچنین گرداننده‌های ثبت‌شده با \f(CW\*(C`atexit\*(C'\fR اجرا می‌شود. .PP اگر یک برنامه اجرایی یک شیء اشتراکی پویا را از طریق سازوکار dlopen بارگذاری کند، گزینه \&\fB\-Wl,\-\-dynamic\-list\-data\fR برای تخلیه تمام داده‌های پروفایل مورد نیاز است. .PP کتابخانه زمان اجرای پروفایلینگ خطاهای مختلف مربوط به دستکاری پروفایل و ذخیره پروفایل را گزارش می‌دهد. خطاها در خروجی خطای استاندارد یا در صورت استفاده از متغیر محیطی در فایل \fBGCOV_ERROR_FILE\fR چاپ می‌شوند. به منظور خاتمه فوری پس از بروز خطا، متغیر محیطی \fBGCOV_EXIT_AT_ERROR\fR را تنظیم کنید. این امر می‌تواند به کاربران در یافتن تداخل پروفایل که منجر به ایجاد یک پروفایل گمراه‌کننده می‌شود کمک کند. .SH "همچنین ببینید (SEE ALSO)" .IX Header "همچنین ببینید (SEE ALSO)" \&\fBgpl\fR\|(7)، \fBgfdl\fR\|(7)، \fBfsf\-funding\fR\|(7)، \fBgcc\fR\|(1) و مدخل Info برای \fIgcc\fR. .SH "کپی‌رایت (COPYRIGHT)" .IX Header "کپی‌رایت (COPYRIGHT)" Copyright (c) 1996\-2026 Free Software Foundation, Inc. .PP اجازه کپی، توزیع و/یا تغییر این سند تحت شرایط مجوز مستندات آزاد گنو (GNU Free Documentation License)، نگارش 1.3 یا هر نگارش بعدی منتشرشده توسط بنیاد نرم‌افزار آزاد اعطا می‌شود؛ با بخش‌های تغییرناپذیر «مجوز عمومی همگانی گنو» و «تأمین مالی نرم‌افزار آزاد»، با متون روی جلد که در (الف) آمده است (زیر را ببینید)، و با متون پشت جلد که در (ب) آمده است (زیر را ببینید). یک نسخه از مجوز در صفحه راهنمای \fBgfdl\fR\|(7) گنجانده شده است. .PP (الف) متن روی جلد FSF عبارت است از: .PP .Vb 1 \& A GNU Manual .Ve .PP (ب) متن پشت جلد FSF عبارت است از: .PP .Vb 3 \& You have freedom to copy and modify this GNU Manual, like GNU \& software. Copies published by the Free Software Foundation raise \& funds for GNU development. .Ve