.\" Copyright (c) 1985, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" Copyright (c) 2002 - 2015 Tony Finch . All rights reserved. .\" .\" This code is derived from software contributed to Berkeley by .\" Dave Yost. It was rewritten to support ANSI C by Tony Finch. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .Dd December 3, 2015 .Dt UNIFDEF 1 PRM .Os " " .Sh "نام (NAME)" .\" unifdef \- حذف دستورات شرطی پیش‌پردازنده از کد .Nm unifdef , unifdefall .Nd حذف دستورات شرطی پیش‌پردازنده از کد .Sh "خلاصه دستور (SYNOPSIS)" .Nm .Op Fl bBcdehKkmnsStV .Op Fl I Ns Ar path .Op Fl [i]D Ns Ar sym Ns Op = Ns Ar val .Op Fl [i]U Ns Ar sym .Ar ... .Op Fl f Ar defile .Op Fl x Bro Ar 012 Brc .Op Fl M Ar backext .Op Fl o Ar outfile .Op Ar infile ... .Nm unifdefall .Op Fl I Ns Ar path .Ar ... .Ar file .Sh "توضیحات (DESCRIPTION)" ابزار .Nm دستورات شرطی .Xr cpp 1 را به صورت انتخابی پردازش می‌کند. این ابزار از فایل ورودی، هم دستورات پیش‌پردازنده و هم هر متن اضافه‌ای را که این دستورات مشخص کرده‌اند باید حذف شود پاک می‌کند، در حالی که بقیه قسمت‌های فایل را بدون تغییر رها می‌سازد. .Pp ابزار .Nm روی خطوط .Ic #if , #ifdef , #ifndef , .Ic #elif , #else , و .Ic #endif عمل می‌کند، و برای این کار از ماکروهای مشخص‌شده در گزینه‌های خط فرمان .Fl D و .Fl U یا در فایل‌های تعاریف .Fl f استفاده می‌نماید. یک دستور زمانی پردازش می‌شود که مشخصات ماکروها برای تعیین یک مقدار قطعی برای عبارت کنترلی آن کافی باشد. اگر نتیجه نادرست (false) باشد، دستور پیش‌پردازنده و خطوط بعدی تحت کنترل آن حذف می‌شوند. اگر نتیجه درست (true) باشد، تنها خود دستور حذف می‌شود. یک دستور .Ic #ifdef یا .Ic #ifndef در صورتی که ماکروی کنترل‌کننده آن مشخص نشده باشد، بدون تغییر عبور داده می‌شود. هر عبارت کنترلی .Ic #if یا .Ic #elif که مقدار نامشخصی داشته باشد یا .Nm قادر به تجزیه آن نباشد، بدون تغییر عبور داده می‌شود. به‌طور پیش‌فرض، .Nm خطوط .Ic #if و .Ic #elif با عبارت‌های ثابت را نادیده می‌گیرد؛ می‌توان با مشخص کردن فلگ .Fl k در خط فرمان، پردازش آن‌ها را درخواست کرد. .Pp این ابزار زیرمجموعه‌ای پرکاربرد از نحو عبارت‌ها را برای خطوط .Ic #if و .Ic #elif پشتیبانی می‌کند: ثوابت عدد صحیح، مقادیر صحیح ماکروهای تعریف‌شده در خط فرمان، عملگر .Fn defined , عملگرهای .Ic \&! , ~ , - (یکانی)، .Ic * , / , % , + , - , .Ic < , <= , > , >= , == , != , & , ^ , \&| , .Ic && , || , و عبارت‌های پرانتزبندی‌شده. تقسیم بر صفر به عنوان مقداری نامشخص در نظر گرفته می‌شود. نوعی ارزیابی .Dq اتصال کوتاه برای عملگر .Ic && استفاده می‌شود: اگر هر یک از عملوندها قطعاً نادرست باشد، نتیجه نادرست خواهد بود، حتی اگر مقدار عملوند دیگر نامشخص باشد. به طور مشابه، اگر هر یک از عملوندهای .Ic || قطعاً درست باشد، نتیجه درست خواهد بود. .Pp هنگام ارزیابی یک عبارت، .Nm ابتدا ماکروها را بسط نمی‌دهد. مقدار یک ماکرو باید یک عدد ساده باشد، نه یک عبارت. شکل محدودی از ارجاع غیرمستقیم مجاز است، به گونه‌ای که مقدار یک ماکرو می‌تواند نام ماکرویی دیگر باشد. .Pp در بیشتر موارد، .Nm تفاوتی میان ماکروهای شیء‌گونه (بدون آرگومان) و ماکروهای تابع‌گونه (دارای آرگومان) قائل نمی‌شود. فراخوانی یک ماکروی تابع‌گونه می‌تواند در عبارت‌های کنترلی .Ic #if و .Ic #elif ظاهر شود. اگر ماکرو به‌طور صریح تعریف نشده باشد، یا با فلگ .Fl D در خط فرمان، یا با .Ic #define در یک فایل تعاریف .Fl f تعریف شده باشد، آرگومان‌های آن نادیده گرفته می‌شوند. اگر ماکرویی به‌طور صریح در خط فرمان با فلگ .Fl U یا با .Ic #undef در یک فایل تعاریف .Fl f لغو تعریف (undefined) شده باشد، نمی‌تواند هیچ آرگومانی داشته باشد، زیرا این کار منجر به خطای نحوی می‌شود. .Pp ابزار .Nm تنها به اندازه‌ای زبان C را درک می‌کند که بداند چه زمانی یکی از دستورات پیش‌پردازنده به دلیل قرار داشتن در یک کامنت غیرفعال است، یا به دلیل شکسته شدن خط با یک خط ادامه‌دار بک‌اسلش، قابل ارزیابی نیست. این ابزار دستورات پیش‌پردازنده با قالب‌بندی نامتعارف را تشخیص می‌دهد و چنانچه ساختار آن‌ها برای مدیریت بیش از حد غیرعادی باشد، آن‌ها را دست‌نخورده عبور می‌دهد. (بخش .Sx "اشکالات (BUGS)" در زیر را ببینید.) .Pp اسکریپتی با نام .Nm unifdefall می‌تواند برای حذف تمام دستورات شرطی .Xr cpp 1 از یک فایل استفاده شود. این اسکریپت از .Nm Fl s و .Nm cpp Fl dM برای دریافت فهرست تمامی ماکروهای کنترل‌کننده و تعاریف آن‌ها (یا نبود آن‌ها) بهره می‌گیرد، سپس .Nm را با آرگومان‌های مناسب جهت پردازش فایل فراخوانی می‌کند. .Sh "گزینه‌ها (OPTIONS)" .Bl -tag -width indent -compact .It Fl D Ns Ar sym Ns = Ns Ar val مشخص می‌کند که یک ماکرو با مقدار داده‌شده تعریف شده است. .Pp .It Fl D Ns Ar sym مشخص می‌کند که یک ماکرو با مقدار 1 تعریف شده است. .Pp .It Fl U Ns Ar sym مشخص می‌کند که یک ماکرو تعریف‌نشده (undefined) است. .Pp اگر یک ماکرو در بیش از یک آرگومان ظاهر شود، آخرین مورد اولویت خواهد داشت. .Pp .It Fl iD Ns Ar sym Ns Op = Ns Ar val .It Fl iU Ns Ar sym رشته‌های C، کامنت‌ها و ادامه‌های خط درون بلوک‌های .Ic #ifdef و .Ic #ifndef که توسط ماکروهای ارائه‌شده با این گزینه‌ها کنترل می‌شوند، نادیده گرفته خواهند شد. .Pp .It Fl f Ar defile فایل .Ar defile شامل دستورات پیش‌پردازنده .Ic #define و .Ic #undef است، که اثری مشابه آرگومان‌های متناظر .Fl D و .Fl U در خط فرمان دارند. می‌توان چندین آرگومان .Fl f داشت و آن‌ها را با آرگومان‌های .Fl D و .Fl U ترکیب کرد؛ گزینه‌های بعدی بر گزینه‌های قبلی تقدم دارند. .Pp هر دستور پیش‌پردازنده باید در یک خط منفرد باشد. تعاریف ماکروهای شیء‌گونه (بدون آرگومان) روی مقدار ارائه‌شده تنظیم می‌شوند. تعاریف ماکروهای تابع‌گونه (دارای آرگومان) به‌گونه‌ای در نظر گرفته می‌شوند که گویی روی 1 تنظیم شده‌اند. .Pp .Em هشدار: لیترال‌های رشته‌ای و ثوابت نویسه‌ای در فایل‌های .Fl f به‌درستی تجزیه نمی‌شوند. .Pp .It Fl b خطوط حذف‌شده را به جای پاک کردن، با خطوط خالی جایگزین می‌کند. این گزینه با گزینه .Fl B مانعة‌الجمع است. .Pp .It Fl B خطوط خالی اطراف یک بخش حذف‌شده را فشرده (یکپارچه) می‌کند. این گزینه با گزینه .Fl b مانعة‌الجمع است. .Pp .It Fl c متمم، یعنی خطوطی که در حالت عادی حذف یا خالی می‌شدند، نگه داشته می‌شوند و برعکس. .Pp .It Fl d چاپ پیام‌های اشکال‌زدایی (دیباگ) را فعال می‌کند. .Pp .It Fl e به‌طور پیش‌فرض، .Nm چنانچه نیاز به حذف یک دستور پیش‌پردازنده داشته باشد که بیش از یک خط گسترش یافته، خطایی را گزارش می‌دهد؛ برای نمونه هنگامی که یک کامنت چندخطی به انتهای سمت راست آن چسبیده باشد. فلگ .Fl e باعث می‌شود به جای آن، چنین خطی نادیده گرفته شود. .Pp .It Fl h راهنما را چاپ می‌کند. .Pp .It Fl I Ns Ar path مکانی اضافی برای جستجوی فایل‌های .Ic #include را به .Nm unifdefall معرفی می‌کند. این گزینه جهت سازگاری با .Xr cpp 1 و ساده‌سازی پیاده‌سازی .Nm unifdefall توسط .Nm نادیده گرفته می‌شود. .Pp .It Fl K همیشه نتیجه عملگرهای .Ic && و .Ic || را در صورتی که هر یک از عملوندها نامشخص باشد، نامشخص تلقی می‌کند، به جای آنکه در شرایطی که عملوند نامشخص نمی‌تواند بر نتیجه اثر بگذارد، ارزیابی اتصال کوتاه انجام دهد. این گزینه برای حفظ سازگاری با نسخه‌های قدیمی‌تر .Nm فراهم شده است. .Pp .It Fl k خطوط .Ic #if و .Ic #elif با عبارت‌های ثابت را پردازش می‌کند. به‌طور پیش‌فرض، بخش‌های کنترل‌شده توسط چنین خطوطی بدون تغییر عبور داده می‌شوند، زیرا معمولاً با .Dq Li "#if 0" شروع می‌شوند و به عنوان نوعی کامنت برای طرح‌ریزی توسعه‌های آینده یا گذشته به کار می‌روند. حذف کردن آن‌ها نادرست است، درست مانند آنچه در مورد کامنت‌های عادی صدق می‌کند. .Pp .It Fl m یک یا چند فایل ورودی را درجا (in place) اصلاح می‌کند. اگر فایل ورودی نیازی به اصلاح نداشته باشد، فایل اصلی حفظ شده و با یک نسخه مشابه رونویسی نمی‌شود. .Pp .It Fl M Ar backext فایل‌های ورودی را درجا اصلاح کرده و با الحاق پسوند .Ar backext به نام فایل‌های ورودی، نسخه‌های پشتیبان از فایل‌های اصلی نگه می‌دارد. یک پسوند .Ar backext با طول صفر، رفتاری مشابه گزینه .Fl m خواهد داشت. .Pp .It Fl n دستورات .Li #line را پس از هر خط حذف‌شده به خروجی اضافه می‌کند، تا خطاهای تولیدشده در حین کامپایل فایل خروجی با شماره خطوط فایل ورودی همخوانی داشته باشند. .Pp .It Fl o Ar outfile هنگام پردازش یک فایل منفرد، خروجی را به جای خروجی استاندارد در فایل .Ar outfile می‌نویسد. .Pp .It Fl s به جای پردازش عادی فایل ورودی، این گزینه باعث می‌شود .Nm فهرستی از ماکروهای مورد استفاده در عبارت‌های کنترلی دستورات پیش‌پردازنده را تولید نماید. .Pp .It Fl S مانند گزینه .Fl s است، اما عمق تودرتویی هر ماکرو نیز چاپ می‌شود. این ویژگی برای پی بردن به تعداد حالت‌های ترکیبی ممکن از ماکروهای وابسته و متقابلِ تعریف‌شده/تعریف‌نشده سودمند است. .Pp .It Fl t تجزیه رشته‌های C، کامنت‌ها و خطوط ادامه‌دار را غیرفعال می‌کند، که برای فایل‌های متنی ساده کاربرد دارد. این گزینه شکل فراگیری از فلگ‌های .Fl iD و .Fl iU است. .Pp .It Fl V اطلاعات نسخه را چاپ می‌کند. .Pp .It Fl x Bro Ar 012 Brc حالت وضعیت خروج را روی صفر، یک یا دو تنظیم می‌کند. برای جزئیات بیشتر به بخش .Sx "وضعیت خروج (EXIT STATUS)" در زیر مراجعه کنید. .El .Pp ابزار .Nm در صورتی که هیچ آرگومان .Ar file داده نشود، ورودی خود را از .Em stdin می‌خواند. در صورت وجود چندین فایل ورودی، حتماً باید از گزینه‌های .Fl m یا .Fl M استفاده کنید. می‌توانید ورودی از stdin یا خروجی به stdout را با .Ql - مشخص نمایید. .Pp ابزار .Nm به‌خوبی با گزینه .Fl D Ns Ar sym از .Xr diff 1 همکاری می‌کند. .Sh "وضعیت خروج (EXIT STATUS)" در استفاده عادی، وضعیت خروج ابزار .Nm به حالتی بستگی دارد که توسط گزینه .Fl x تنظیم شده باشد. .Pp اگر حالت خروج صفر باشد (پیش‌فرض)، .Nm در صورت تطابق کامل خروجی با ورودی، با وضعیت 0 و در صورت وجود تفاوت، با وضعیت 1 خارج می‌شود. .Pp اگر حالت خروج یک باشد، .Nm در صورت تغییر نیافتن خروجی با وضعیت 1 و در صورت وجود تفاوت با وضعیت 0 خارج می‌شود. .Pp اگر حالت خروج دو باشد، .Nm در هر دو مورد با وضعیت صفر خارج می‌گردد. .Pp در تمامی حالت‌های خروج، چنانچه خطایی رخ دهد، .Nm با وضعیت 2 خارج خواهد شد. .Pp در صورت ارائه گزینه‌های خط فرمان .Fl h یا .Fl V , وضعیت خروج 0 خواهد بود. .Sh "عیب‌یابی (DIAGNOSTICS)" .Bl -item .It .Tn EOF درون کامنت .It دستور نامناسب .Ic #elif , .Ic #else یا .Ic #endif .It نام ماکرو در #define یا #undef جا افتاده است .It خط کنترلی پیش‌پردازنده مبهم است .It رسیدن زودهنگام به پایان فایل .Tn (EOF) (همراه با شماره خط مربوط به آخرین .Ic #if بسته نشده) .It تعداد سطوح تودرتویی بیش از حد مجاز است .It دستور پیش‌پردازنده ناشناخته است .It لیترال نویسه‌ای یا رشته‌ای بسته نشده است .El .Sh "همچنین ببینید (SEE ALSO)" .Xr cpp 1 , .Xr diff 1 .Pp صفحه خانگی unifdef عبارت است از: .Pa http://dotat.at/prog/unifdef .Sh "تاریخچه (HISTORY)" دستور .Nm در .Bx 2.9 ارائه شد. پشتیبانی از .Tn ANSI\~C در .Fx 4.7 اضافه گردید. .Sh "نویسندگان (AUTHORS)" .An -nosplit پیاده‌سازی اصلی توسط .An Dave Yost Aq Mt Dave@Yost.com نوشته شده است. .An Tony Finch Aq Mt dot@dotat.at آن را برای پشتیبانی از .Tn ANSI\~C بازنویسی کرد. .Sh "اشکالات (BUGS)" .Bl -bullet .It ارزیابی عبارت‌ها بسیار محدود است. .It ثوابت نویسه‌ای ارزیابی نمی‌شوند. لیترال‌های رشته‌ای و ثوابت نویسه‌ای در فایل‌های تعاریف .Fl f به جای تجزیه به عنوان بخشی از توکن‌های جایگزین ماکرو، نادیده گرفته می‌شوند. .It تنها فرم پایه لیترال‌های رشته خام ++C شناخته می‌شود، مانند .Li R"(string)" بدون جداکننده‌ها همانند .Li R"delimiter(string)delimiter" . .It فایل‌های مبدأ در هر نوبت یک خط پردازش می‌شوند، بنابراین دستورات پیش‌پردازنده‌ای که در چند خط فیزیکی پخش شده‌اند (به دلیل کامنت‌ها یا بک‌اسلش و رفتن به خط بعد) در تمامی موقعیت‌ها قابل رسیدگی نیستند. .It سه‌نویسه‌ها (Trigraphs) پشتیبانی نمی‌شوند. .It هیچ پشتیبانی از ماکروهایی با تعاریف مختلف در نقاط گوناگون فایل مبدأ وجود ندارد. .It عملکرد حالت متنی و نادیده‌گیری با رفتار نسخه‌های مدرن .Xr cpp 1 همخوانی ندارد. .El .Pp لطفاً گزارش اشکالات را با ایمیل به نشانی .Aq Mt dot@dotat.at ارسال فرمایید.