<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Aryan Arora's blog]]></title><description><![CDATA[Aryan Arora's blog]]></description><link>https://aryanarora.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Fri, 23 Feb 2024 07:40:00 GMT</lastBuildDate><atom:link href="https://aryanarora.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><atom:link rel="next" href="https://aryanarora.hashnode.dev/rss.xml?page=1"/><item><title><![CDATA[Cleaning C code to maintain sanity]]></title><description><![CDATA[<p>I am the kind of person who can ignore scattered and untidy surroundings, but when it comes to messy code, I cannot resist cleaning and refactoring it.<br />This blog mostly covers the aspect of code refactoring.</p><p>Let's get started.</p><p>Suppose we've built a Random Coordinates Generator in C. If we put all our code in a single file, it'll look like this.<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1663593550041/nS9YZEIGL.png?width=600" alt="monolith.png" class="image--center mx-auto" />Output:<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1663593632645/g2GrEddN5.png?width=600" alt="o.png" class="image--center mx-auto" /></p><p>The code is quite self-explanatory, just give it a read you'll get the idea of what's going on.</p><h2 id="heading-refactoring-begins">Refactoring Begins</h2><p>To get started on refactoring, firstly, we'll separate the code in  <code>.c</code> and header <code>.h</code>  files, adding <strong>function signature/declaration</strong> in <code>.h</code> file and <strong>function definition</strong> in <code>.c</code> file.</p><p><strong>Header File</strong> is a file that contains function declarations and macro definitions.</p><p>Now, the question is, <strong>Why header files? Why not only separate <code>.c</code> files?</strong><strong>Abstractionnn...</strong><br />To create reliable and robust code bases, we need to follow some principles, one of which is abstraction. </p><p>Hiding implementation makes the code more maintainable and less dependent.</p><p>After refactoring, our file tree will look like this:</p><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1663593667542/Kbnylmb8Q.png?width=600" alt="ft.png" class="image--center mx-auto" /></p><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1663593689000/gP4DkRN7o.png?width=600" alt="h1.png" class="image--center mx-auto" /><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1663593775259/oQPRYbf3t.png?width=600" alt="c1.png" class="image--center mx-auto" /><code>coordinate.h</code> file doesn't know the implementation of the declared functions.</p><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1663594340932/uqEIZc4mb.png?width=600" alt="h2.png" class="image--center mx-auto" /><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1663594378807/kg7GuaMRS.png?width=600" alt="c2.png" class="image--center mx-auto" /><code>random_coordinates.c</code> uses functions from <code>coordinate.h</code> but does not know its implementation details.</p><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1663594415862/ydCnoPf-q.png?width=600" alt="m.png" class="image--center mx-auto" />Look how clean is our <code>main()</code> function now.Our <code>main.c</code> file also does not know the implementation of <code>print_random_coordinates()</code> as only the header file is included.</p><p>Now, comes the question: <strong><code>coordinate.c</code> and <code>random_coordinates.c</code> are not included anywhere, so how come our program gets to know their implementation?</strong><br />During compilation, we link both the required <code>.c</code> files with the <code>main.c</code> file.<code>gcc main.c coordinate.c random_coordinates.c -o main</code></p><p>A couple of lines of code that start with <code>#ifndef FILENAME</code> may be causing you an itch in the brain. Those are known as <strong>"include guards"</strong>.</p><h2 id="heading-why-and-how-to-use-include-guards">Why and How to use "INCLUDE Guards"?</h2><p>Suppose we have two headers and the <code>first.h</code> includes <code>second.h</code> and the <code>main.c</code> include both <code>first.h</code> and <code>second.h</code> Now, this will cause the <code>main.c</code> to have a double implementation of the functions in <code>second.h</code>.To avoid this, we use "include guards":</p><p>Usage:</p><pre><code class="lang-C"><span class="hljs-meta">#<span class="hljs-meta-keyword">ifndef</span> UNIQUE_NAME</span><span class="hljs-meta">#<span class="hljs-meta-keyword">define</span> UNIQUE_NAME</span>function_signature()<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span></code></pre><p>These <a target="_blank" href="https://www.scaler.com/topics/c/macros-in-c/">macros</a> do the following:If UNIQUE_NAME is not defined before then,<br />define UNIQUE_NAME and include the header</p><p>If this header is included for second time in the same scope,<br />then the <code>#ifndef</code> condition is not satisfied, and the lines after <code>#ifndef</code> are not read as <code>#endif</code> is executed just after <code>#ifndef</code>.</p><hr /><p>I hope you learned something. Be sure to leave a comment!Check out my github <a target="_blank" href="https://github.com/aryanA101a/clean_c_code_template">repo</a> for this code.</p>]]></description><link>https://aryanarora.hashnode.dev/cleaning-c-code-to-maintain-sanity</link><guid isPermaLink="true">https://aryanarora.hashnode.dev/cleaning-c-code-to-maintain-sanity</guid><dc:creator><![CDATA[Aryan Arora]]></dc:creator><pubDate>Wed, 21 Sep 2022 06:23:32 GMT</pubDate><cover_image>https://cdn.hashnode.com/res/hashnode/image/upload/v1663573600763/hYulG_3R6.jpeg</cover_image></item><item><title><![CDATA[What I learned while making a text editor like Nano from scratch in C?]]></title><description><![CDATA[<p>Ordinarily, I do not create such low-level projects, but as I was getting more inclined towards systems-programming I had to do something to get my feet wet in this domain. And while creating this project, I got mesmerized by the level of detail which I had to take care of while implementing every feature. Also, I got to know why C is harassed for memory management.</p><p>This text editor works just like the legendary nano text editor.</p><p>I'll articulate my learnings while explaining how this text editor works.</p><h2 id="heading-taking-input-from-the-keyboard">Taking input from the keyboard</h2><h3 id="heading-read">read()</h3><p>I've used <code>read()</code> system call which is available under <code>&lt;unistd.h&gt;</code> . <code>read()</code> gives us fine-grained control over taking input as we need to specify the file descriptor and the number of bytes.</p><p><strong>Syntax: <code>size_t read (int fileDescriptor, void* buffer, size_t noFoBytes)</code></strong></p><h3 id="heading-timeout-for-read">Timeout for read</h3><p><code>read()</code> is a blocking system call which means it will wait indefinitely for input to be taken, therefore it may have poor performance implications.So, we'll add a time out for read by setting terminal attributes <code>VMIN</code> and <code>VTIME</code> to 0 and 1, which means read returns as soon as there is any input and timeouts every 1/10th of a second.</p><h3 id="heading-canonical-mode-vs-raw-mode">Canonical Mode vs Raw Mode</h3><p>As we'll be entirely working with the terminal, we need to dive into the little details.By default, the terminal comes in <strong>canonical mode,</strong> which means the keyboard input only gets to the program after we press enter.To take everything into our hands we'll need to enter <strong>raw mode</strong>.Entering raw mode is not as easy as pressing a switch, we'll need to change a couple of terminal attributes such as:</p><ol><li><strong>Turn off echoing</strong> which means we'll turn off the terminal's default way of rendering text onto the screen.</li><li><strong>Disable Ctrl-C and Ctrl-Z signals</strong> as we do not want to kill or suspend our editor without gracefully handling everything.</li><li><strong>Disable Ctrl-S and Ctrl-Q signals</strong> Ctrl-S stops data from being transmitted into the terminal until you press Ctrl-Q</li><li><strong>Disable Ctrl-V</strong> Ctrl-V lets you take a character literally which means it allows us to embed a control character. We'll discuss control characters later.</li><li><strong>Fix Ctrl-M</strong> Ctrl-M is the control character for carriage-return("\r") but our terminal adds a newline after it.</li><li><strong>Turn off output processing</strong> By default terminal adds carriage-return after newline("\n"). We'll discuss carriage return later.</li></ol><p>Terminal attributes can be read by <code>tcgetattr()</code> into <code>termios</code> struct and set by <code>tcsetattr()</code>.</p><p><strong>Carriage Return('\r')</strong> brings cursor to the extreme left and <strong>Newline('\n')</strong> brings the cursor to the next line at the same position where it was in the previous line.</p><h2 id="heading-handling-errors">Handling Errors</h2><p>We use <code>perror()</code> to handle errors as it looks at the global <code>errno</code> and prints a descriptive error message. It also prints the string given to it, before printing the error message.</p><h2 id="heading-how-do-we-map-ctrl-alphabetic-keys">How do we map Ctrl + alphabetic keys?</h2><p><strong>Control Characters</strong> are non-printing characters that are utilized to serve a purpose.</p><p>q has a binary ASCII value of <code>01010001</code> and CTRL-q has <code>10001</code>. If you'll try to observe you'll realize that bits after 5th bit are stripped. Well, ASCII values are designed in this way on purpose.Now, we know how things work so create a bit-mask to do the same and apply it to the alphabetic keys.</p><h2 id="heading-outputting-to-the-screen">Outputting to the screen</h2><h3 id="heading-write">write()</h3><p><code>write()</code> is a system call that takes the file descriptor and number of bytes.<strong>Syntax:</strong> <code>size_t write (int fileDescriptor, void* buffer, size_t numberOfBytes);</code></p><h3 id="heading-escape-sequences">Escape Sequences</h3><p>These are special character sequences that instruct the terminal to do various tasks such as text formatting, moving the cursor, and clearing the screen. We'll use <strong>ANSI</strong> escape sequences which start with <code>'\x1b'</code> which in itself translates to escape key, followed by a [.</p><p><strong><code>&lt;esc&gt;[2J</code> clears the entire screen.</strong><code>0</code> clears from the cursor to the end of the screen.<code>1</code> clears the screen up to the position of the cursor.</p><p><strong><code>&lt;esc&gt;[H</code> positions the cursor to top left.</strong><code>&lt;esc&gt;[5;7H</code> will position the cursor to the specified row and col number.</p><h3 id="heading-window-size">Window Size</h3><p>I used <code>ioctl()</code> to get window size and, I also had to implement a fallback method if ioctl() failed to work for some reason.Another way we can get the window size is by pushing the cursor bottom-right as far as possible without going out of bounds by using this escape sequence <code>"\x1b[999C\x1b[999B"</code> and then query the position of the cursor by using <code>"\x1b[6n"</code>.</p><h3 id="heading-screen-refresh">Screen Refresh</h3><p>After every keypress, we refresh the screen. To refresh the screen we clear one line at a time using <code>""\x1b[K""</code> and then append the same/modified line data.</p><hr /><p>There's a lot more to tell, but it'll need more context to explain. So this is it.</p><p>If you enjoyed reading this you'll enjoy x100 <a target="_blank" href="https://viewsourcecode.org/snaptoken/kilo/">creating</a> it.</p><p>Check out my <a target="_blank" href="https://github.com/aryanA101a/nin">editor</a>. It works on Linux and may work on Mac OS.</p>]]></description><link>https://aryanarora.hashnode.dev/what-i-learned-while-making-a-text-editor-like-nano-from-scratch-in-c</link><guid isPermaLink="true">https://aryanarora.hashnode.dev/what-i-learned-while-making-a-text-editor-like-nano-from-scratch-in-c</guid><dc:creator><![CDATA[Aryan Arora]]></dc:creator><pubDate>Sun, 28 Aug 2022 16:38:45 GMT</pubDate><cover_image>https://cdn.hashnode.com/res/hashnode/image/upload/v1661695225521/33yn8dxr-.png</cover_image></item></channel></rss>