Translation

(itstool) path: sect2/para
English
In a high-level language, such as C, there are several main approaches. One is to use a <function role="statement">switch</function> statement which chooses what function should be run. For example,
181/1980
Context English Persian State
If the input is anything other than a carriage return or line feed, output a line feed, then output the input, then change the state to <symbol>ordinary</symbol>. اگر ورودی چیز به‌غیر از یک سرسطر یا نوسطر باشد، یک نوسطر ایجاد کنید، سپس ورودی را ایجاد کنید، سپس حالت را به <symbol>ordinary</symbol> تغییر دهید.
If the input is a carriage return, we have received two (or more) carriage returns in a row. We discard the input, we output a line feed, and leave the state unchanged. اگر ورودی یک سرسطر باشد، ما دو (یا بیشتر) سرسطر پشت سر هم دریافت کرده‌ایم. ورودی را حذف می‌کنیم، یک نوسطر ایجاد می‌کنیم، و حالت را تغییر نمی‌دهیم.
If the input is a line feed, we output the line feed and change the state to <symbol>ordinary</symbol>. Note that this is not the same as the first case above – if we tried to combine them, we would be outputting two line feeds instead of one. اگر ورودی یک نوسطر باشد، نوسطر را ایجاد می‌کنیم و حالت را به <symbol>ordinary</symbol> تغییر می‌دهیم. توجه داشته باشید که این همانند مورد بالا نیست - اگر سعی می‌کردیم آنها را ترکیب کنیم، به‌جای یک نوسطر دو نوسطر ایجاد می‌کردیم.
Finally, we are in the <symbol>lf</symbol> state after we have received a line feed that was not preceded by a carriage return. This will happen when our file already is in <trademark class="registered">UNIX</trademark> format, or whenever several lines in a row are expressed by a single carriage return followed by several line feeds, or when line ends with a line feed / carriage return sequence. Here is how we need to handle our input in this state: در انتها، هنگامی‌که در حالت <symbol>lf</symbol> هستیم نوسطری دریافت کرده‌ایم که توسط یک سرسطر دنبال نشده است. این اتفاق هنگامی‌ میفتد که پروندهٔ ما از قبل در قالب <trademark class="registered">UNIX</trademark> باشد، یا هر زمان که به‌همراه تعدادی نوسطر، تعدادی سطر در یک ردیف توسط یک سرسطر نمایان شده باشند، یا زمانی‌که سطر با یک دنبالهٔ نوسطر / سرسطر به‌پایان می‌رسد. ما باید بدین شکل ورودی خود را در این حالت سامان‌دهی کنیم:
If the input is anything other than a carriage return or line feed, we output a line feed, then output the input, then change the state to <symbol>ordinary</symbol>. This is exactly the same action as in the <symbol>cr</symbol> state upon receiving the same kind of input. چنانچه ورودی چیزی به‌غیر از سرسطر یا نوسطر باشد، ما یک نوسطر ایجاد می‌کنیم، سپس ورودی را ایجاد می‌کنیم، سپس حالت را به <symbol>ordinary</symbol> تغییر می‌دهیم. این دقیقاً همان عملی است که هنگام دریافت ورودی مشابه در حالت <symbol>cr</symbol> وجود دارد.
If the input is a carriage return, we discard the input, we output a line feed, then change the state to <symbol>ordinary</symbol>. چنانچه ورودی یک سرسطر باشد، آن را حذف می‌کنیم، یک نوسطر ایجاد می‌کنیم، سپس حالت را به <symbol>ordinary</symbol> تغییر می‌دهیم.
If the input is a line feed, we output the line feed, and leave the state unchanged. چنانچه ورودی نوسطر باشد، نوسطر را ایجاد می‌کنیم، و حالت را تغییر نمی‌دهیم.
The Final State حالت نهایی
The above <emphasis>finite state machine</emphasis> works for the entire file, but leaves the possibility that the final line end will be ignored. That will happen whenever the file ends with a single carriage return or a single line feed. I did not think of it when I wrote <application>tuc</application>, just to discover that occasionally it strips the last line ending. <emphasis>دستگاه حالت متناهی</emphasis> فوق برای تمام پرونده کار می‌کند، اما این احتمال را می‌دهد که انتهای سطر پایانی نادیده گرفته ‌شود. این امر هرزمان که پرونده با یک سرسطر یا نوسطر پایان بپذیرد اتفاق میفتد. در هنگام نوشتن <application>tuc</application> به آن فکر نکردم، که متوجه شدم گاهی اوقات پایان آخرین سطر را حذف می‌کند.
This problem is easily fixed by checking the state after the entire file was processed. If the state is not <symbol>ordinary</symbol>, we simply need to output one last line feed. این مسئله به‌آسانی با بررسی حالت پس از پردازش تمام پرونده رفع می‌شود. اگر حالت <symbol>ordinary</symbol> نباشد، ما تنها باید آخرین نوسطر را ایجاد کنیم.
Now that we have expressed our algorithm as a <emphasis>finite state machine</emphasis>, we could easily design a dedicated digital electronic circuit (a "chip") to do the conversion for us. Of course, doing so would be considerably more expensive than writing an assembly language program. اکنون که الگوریتم خود را به‌عنوان یک <emphasis>دستگاه حالت متناهی</emphasis> معرفی کرده‌ایم، می‌توانیم به آسانی یک مدار الکترونیکی دیجیتال اختصاصی (یک "تراشه") طراحی کنیم تا کار تبدیل را برای ما انجام دهد. البته، انجام آن بسیار هزینه‌بر تر از نوشتن یک برنامه‌ در زبان همگذاری است.
The Output Counter شمارندهٔ خروجی
Because our file conversion program may be combining two characters into one, we need to use an output counter. We initialize it to <constant>0</constant>, and increase it every time we send a character to the output. At the end of the program, the counter will tell us what size we need to set the file to. از آنجا که برنامهٔ تبدیل‌کنندهٔ پروندهٔ ما ممکن است دو نویسه را در یک نویسه ترکیب کند، ما به یک شمارندهٔ‌ خروجی نیاز داریم. آن را در <constant>0</constant> آغاز می‌کنیم، و هر زمان که نویسه‌ای را به خروجی ارسال می‌کنیم آن را افزایش می‌دهیم. در پایان برنامه، شمارنده اندازه‌ای که باید پرونده را در آن تنظیم کرد به ما می‌گوید.
Implementing FSM in Software پیاده‌سازی FSM در نرم‌افزار
The hardest part of working with a <emphasis>finite state machine</emphasis> is analyzing the problem and expressing it as a <emphasis>finite state machine</emphasis>. That accomplished, the software almost writes itself. مشکل‌ترین بخش کار با یک <emphasis>دستگاه حالت متناهی</emphasis> تجزیه و تحلیل مشکل و معرفی آن به‌عنوان یک <emphasis>دستگاه حالت متناهی</emphasis> است. با رسیدن به این مقصود، نرم‌افزار تقریباً‌ خودش را می‌نویسد.
In a high-level language, such as C, there are several main approaches. One is to use a <function role="statement">switch</function> statement which chooses what function should be run. For example, در یک زبان سطح بالا، مانند C، چندین رویکرد اصلی وجود دارد. یکی استفاده از عبارت <function role="statement">switch</function> است که انتخاب می‌کند کدام تابع باید اجرا شود. برای مثال،
switch (state) {
default:
case REGULAR:
regular(inputchar);
break;
case CR:
cr(inputchar);
break;
case LF:
lf(inputchar);
break;
}
switch (state) {
default:
case REGULAR:
regular(inputchar);
break;
case CR:
cr(inputchar);
break;
case LF:
lf(inputchar);
break;
}
Another approach is by using an array of function pointers, something like this: روشی دیگر استفاده از یک آرایه از اشاره‌گرهای تابع است، چیزی مانند این:
(output[state])(inputchar); (output[state])(inputchar);
Yet another is to have <varname>state</varname> be a function pointer, set to point at the appropriate function: با این‌حال روش دیگر داشتن <varname>state</varname> به‌عنوان یک اشاره‌گر تابع است، که برای اشاره کردن به تابع مورد نظر تنظیم شود:
(*state)(inputchar); (*state)(inputchar);
This is the approach we will use in our program because it is very easy to do in assembly language, and very fast, too. We will simply keep the address of the right procedure in <varname role="register">EBX</varname>, and then just issue: این روشی‌ست که ما در برنامهٔ خودمان استفاده می‌کنیم زیرا استفاده از آن در زبان همگذاری بسیار آسان است، و همچنین بسیار سریع. نشانی روش صحیح را در <varname role="register">EBX</varname> نگه می‌داریم، و سپس می‌نویسیم:
call ebx call ebx
This is possibly faster than hardcoding the address in the code because the microprocessor does not have to fetch the address from the memory—it is already stored in one of its registers. I said <emphasis>possibly</emphasis> because with the caching modern microprocessors do, either way may be equally fast. این روش احتمالاً سریع‌تر از سخت‌کد کردن نشانی در کد است زیرا ریزپردازنده نیازی به گرفتن نشانی از حافظه ندارد—از پیش در یکی از ثبات‌هایش ذخیره شده است. من گفتم <emphasis>احتمالاً</emphasis> زیرا با ذخیره‌سازی‌ای که ریزپردازنده‌های امروزی انجام می‌دهند، هر دو روش ممکن است به یک اندازه سریع باشند.
Memory Mapped Files پرونده‌های حافظه نگاشت‌شده
Because our program works on a single file, we cannot use the approach that worked for us before, i.e., to read from an input file and to write to an output file. از آنجه که برنامهٔ ما در یک پروندهٔ واحد کار می‌کند، نمی‌توانیم از روشی که پیش‌تر به ما جواب داده است استفاده کنیم، برای مثال، خواندن از یک پروندهٔ ورودی و نوشتن در یک پروندهٔ خروجی.
<trademark class="registered">UNIX</trademark> allows us to map a file, or a section of a file, into memory. To do that, we first need to open the file with the appropriate read/write flags. Then we use the <function role="syscall">mmap</function> system call to map it into the memory. One nice thing about <function role="syscall">mmap</function> is that it automatically works with virtual memory: We can map more of the file into the memory than we have physical memory available, yet still access it through regular memory op codes, such as <function role="opcode">mov</function>, <function role="opcode">lods</function>, and <function role="opcode">stos</function>. Whatever changes we make to the memory image of the file will be written to the file by the system. We do not even have to keep the file open: As long as it stays mapped, we can read from it and write to it. <trademark class="registered">UNIX</trademark> این امکان را به ما می‌دهد تا یک پرونده، یا قسمتی از یک پرونده را نگاشت کنیم. برای انجام آن، ابتدا باید پرونده را با نشان‌های خواندن/نوشتن مناسب باز کنیم. سپس از فراخوان سامانهٔ <function role="syscall">mmap</function> برای نگاشت آن در حافظه استفاده می‌کنیم. یک چیز خوب در مورد <function role="syscall">mmap</function> این است که به‌طور خودکار با حافظهٔ مجازی کار می‌کند: می‌توانیم نسبت به حافظهٔ فیزیکی موجودی که داریم قسمت بیش‌تری از پرونده را در حافظه نگاشت کنیم، اما در عین حال به‌واسطهٔ کدهای دستوری معمولی به آن دسترسی داشته باشیم، مانند <function role="opcode">mov</function>، <function role="opcode">lods</function>، و <function role="opcode">stos</function>. هر تغییری که در تصویر حافظهٔ پرونده ایجاد می‌کنیم از طریق سامانه در پرونده نوشته می‌شود. حتی نیازی به باز نگاه داشتن پرونده نیست: تا زمانی که نگاشت‌شده بماند، می‌توانیم از آن بخوانیم و در آن بنویسیم.
The 32-bit Intel microprocessors can access up to four gigabytes of memory – physical or virtual. The FreeBSD system allows us to use up to a half of it for file mapping. ریزپردازنده‌های ۳۲ بیتی اینتل می‌توانند تا ۴ گیگابایت از حافظه دسترسی داشته باشند - فیزیکی یا مجازی. سامانهٔ FreeBSD به ما این امکان را می‌دهد تا نیمی از آن را برای نگاشت پرونده استفاده کنیم.
For simplicity sake, in this tutorial we will only convert files that can be mapped into the memory in their entirety. There are probably not too many text files that exceed two gigabytes in size. If our program encounters one, it will simply display a message suggesting we use the original <application>tuc</application> instead. به‌خاطر سادگی، ما در این آموزه تنها پرونده‌هایی را که به‌طور کامل می‌توانند در حافظه نگاشته شوند را تبدیل می‌کنیم. احتمالاً پرونده‌های متنی بسیاری وجود ندارند که اندازه‌شان از ۲ گیگابایت فراتر رود. اگر برنامهٔ ما با یکی از آنها برخورد کند، پیامی نمایش می‌دهد که پیشنهاد می‌دهد به جای آن از <application>tuc</application> اصلی استفاده کنیم.
If you examine your copy of <filename>syscalls.master</filename>, you will find two separate syscalls named <function role="syscall">mmap</function>. This is because of evolution of <trademark class="registered">UNIX</trademark>: There was the traditional <acronym>BSD</acronym> <function role="syscall">mmap</function>, syscall 71. That one was superseded by the <acronym><trademark class="registered">POSIX</trademark></acronym> <function role="syscall">mmap</function>, syscall 197. The FreeBSD system supports both because older programs were written by using the original <acronym>BSD</acronym> version. But new software uses the <acronym><trademark class="registered">POSIX</trademark></acronym> version, which is what we will use. اگر نسخهٔ خود از <filename>syscalls.master</filename> را بیازمایید، با دو فراخوان سامانهٔ جداگانه به نام <function role="syscall">mmap</function> مواجه می‌شوید. این به خاطر سیر تکاملی <trademark class="registered">UNIX</trademark> است: یک فراخوان سامانهٔ سنتی داشتیم، <acronym>BSD</acronym><function role="syscall">mmap</function> فراخون سامانهٔ 71. آن فراخوان توسط <acronym><trademark class="registered">POSIX</trademark></acronym><function role="syscall">mmap</function>، فراخوان سامانهٔ 197 جایگزین شد. سامانهٔ FreeBSD از هر دوی آنها پشتیبانی می‌کند زیرا برنامه‌های قدیمی به‌وسیلهٔ نسخهٔ اصلی <acronym>BSD</acronym> نگاشته شده‌اند. اما نرم‌افزار جدید از نسخهٔ <acronym><trademark class="registered">POSIX</trademark></acronym> استفاده می‌کند، که همان چیزیست که استفاده می‌کنیم.
The <filename>syscalls.master</filename> lists the <acronym><trademark class="registered">POSIX</trademark></acronym> version like this: <filename>syscalls.master</filename> نسخهٔ <acronym><trademark class="registered">POSIX</trademark></acronym> را بدین شکل فهرست می‌کند:

Loading…

In a high-level language, such as C, there are several main approaches. One is to use a <function role="statement">switch</function> statement which chooses what function should be run. For example,
در یک زبان سطح بالا، مانند C، چندین رویکرد اصلی وجود دارد. یکی استفاده از عبارت <function role="statement">switch</function> است که انتخاب می‌کند کدام تابع باید اجرا شود. برای مثال،
3 months ago
Browse all component changes

Glossary

English Persian
Function library کتابخانهٔ توابع FreeBSD Doc
Switch سوده FreeBSD Doc

Source information

Source string comment
(itstool) path: sect2/para
Source string location
book.translate.xml:11598
String age
6 months ago
Source string age
a year ago
Translation file
books/fa/developers-handbook.po, string 1858