<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Uman Shahzad</title>
    <description>The latest articles on DEV Community by Uman Shahzad (@mslm_uman).</description>
    <link>https://dev.to/mslm_uman</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1273529%2F2d9b111d-cdde-4668-a42f-162e2b46af13.jpg</url>
      <title>DEV Community: Uman Shahzad</title>
      <link>https://dev.to/mslm_uman</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mslm_uman"/>
    <language>en</language>
    <item>
      <title>Oxylabs Python SDK</title>
      <dc:creator>Uman Shahzad</dc:creator>
      <pubDate>Mon, 24 Jun 2024 06:23:25 +0000</pubDate>
      <link>https://dev.to/mslm_uman/oxylabs-python-sdk-4j5c</link>
      <guid>https://dev.to/mslm_uman/oxylabs-python-sdk-4j5c</guid>
      <description>&lt;p&gt;Hello everyone! We've created a Python SDK for the Oxylabs Scraper APIs to help simplify integrating with Oxylabs's APIs.&lt;/p&gt;

&lt;p&gt;You can find it here: &lt;a href="https://pypi.org/project/oxylabs/"&gt;https://pypi.org/project/oxylabs/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Would appreciate if Oxylabs users could try it out and give their feedback so we can start addressing it and improving the SDK.&lt;/p&gt;

&lt;p&gt;Here's a quick start example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;oxylabs&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RealtimeClient&lt;/span&gt;

&lt;span class="c1"&gt;# Set your Oxylabs API Credentials.
&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;username&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;password&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# Initialize the SERP Realtime client with your credentials.
&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RealtimeClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Use `bing_search` as a source to scrape Bing with nike as a query.
&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;serp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scrape_search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nike&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works with both the real-time and async integration methods and makes it especially easy to use the latter method which is otherwise quite tedious.&lt;/p&gt;

&lt;p&gt;Source code is at &lt;a href="https://github.com/oxylabs/oxylabs-sdk-python"&gt;https://github.com/oxylabs/oxylabs-sdk-python&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you!&lt;/p&gt;

</description>
      <category>oxylabs</category>
      <category>python</category>
      <category>api</category>
      <category>library</category>
    </item>
    <item>
      <title>How To Make A Custom Splunk Command</title>
      <dc:creator>Uman Shahzad</dc:creator>
      <pubDate>Mon, 05 Feb 2024 23:34:30 +0000</pubDate>
      <link>https://dev.to/mslm_uman/how-to-make-a-custom-splunk-command-ncm</link>
      <guid>https://dev.to/mslm_uman/how-to-make-a-custom-splunk-command-ncm</guid>
      <description>&lt;h2&gt;
  
  
  Step 0: Understanding the types of commands
&lt;/h2&gt;

&lt;p&gt;You can think of Splunk custom search commands as specialized command components within Splunk apps that understand your unique needs.&lt;/p&gt;

&lt;p&gt;Each command has a specific type that serves as the boundary of how it can work and interact with other commands. Here are the different types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Streaming commands&lt;/strong&gt;: Process results in one event at a time, applying transformations individually.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transforming commands&lt;/strong&gt;: Arrange results into a data table for statistical analysis.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generating commands&lt;/strong&gt;: Retrieve information from indexes without modifications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dataset processing commands&lt;/strong&gt;: Require the complete dataset before execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0Kmrbtfm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://tinypic.host/images/2024/01/28/Splunk-Custom-Command.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0Kmrbtfm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://tinypic.host/images/2024/01/28/Splunk-Custom-Command.png" alt="Custom search commands" width="800" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From here, let's take everything in steps - by completing the 4 easy steps below, you'll have a functioning custom search command.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Setting up your Splunk environment
&lt;/h2&gt;

&lt;p&gt;Let's first get the Splunk home directory under control.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$SPLUNK_HOME&lt;/code&gt; is an environment variable used in various places and it depends on where you have installed Splunk Enterprise on your machine. Please set it to the right directory before continuing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;On Linux or macOS&lt;/strong&gt;: Open a terminal window and type &lt;code&gt;echo $SPLUNK_HOME&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On Windows&lt;/strong&gt;: Open a Command Prompt window and type &lt;code&gt;echo %SPLUNK_HOME%&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now in order to execute a custom command, we must first have Splunk Enterprise running. Please download the most recent version of &lt;a href="https://www.splunk.com/en_us/download/splunk-enterprise.html"&gt;Splunk Enterprise&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After downloading and unpacking, you can launch Splunk via the terminal by executing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$SPLUNK_HOME&lt;/span&gt;/bin/splunk start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this is successful, Splunk Enterprise will be available at &lt;a href="http://localhost:8000"&gt;http://localhost:8000&lt;/a&gt; in your browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sx2sL_xE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://tinypic.host/images/2024/01/26/Splunk-Sign-In-Page.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sx2sL_xE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://tinypic.host/images/2024/01/26/Splunk-Sign-In-Page.png" alt="Sign In Page" width="800" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To create an app, open the above page and navigate to &lt;code&gt;Manage Apps&lt;/code&gt;, click the &lt;code&gt;Create app&lt;/code&gt; button, and enter your app's name along with some additional information like folder name, version, author and description.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--b8cN-pZ7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://tinypic.host/images/2024/01/26/Splunk-Create-App-Form.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--b8cN-pZ7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://tinypic.host/images/2024/01/26/Splunk-Create-App-Form.png" alt="Create App Form" width="800" height="648"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By pressing "Save!", you'll now have a Splunk app and can access the app's directory at &lt;code&gt;$SPLUNK_HOME/etc/apps/my_cutom_command_app/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now that we have a container for custom commands, you must choose a programming language to write the code of the command in.&lt;/p&gt;

&lt;p&gt;Python is the most popular language used among Splunk developers and we'll be using that going forward, but you can also use Java - the choice is yours!&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Writing the script for your command
&lt;/h2&gt;

&lt;p&gt;Let's assume our custom command name is &lt;code&gt;my_custom_command&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now that the entire environment for the custom command has been configured, we need to create a script for it at &lt;code&gt;$SPLUNK_HOME/etc/my_cutom_command_app/bin/my_custom_command.py&lt;/code&gt;. Note that the name of the script (the &lt;code&gt;.py&lt;/code&gt; file) is the same as the command name - this is not required, but good practice.&lt;/p&gt;

&lt;p&gt;For writing the script we need the &lt;a href="https://github.com/splunk/splunk-sdk-python/"&gt;Splunk Enterprise SDK for Python&lt;/a&gt;, which you can copy and paste into the following folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$SPLUNK_HOME/etc/my_cutom_command_app/bin/splunklib
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RP89w6sT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://tinypic.host/images/2024/01/26/Splunk-SDK-Splunklib.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RP89w6sT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://tinypic.host/images/2024/01/26/Splunk-SDK-Splunklib.png" alt="Splunklib" width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Below are examples of each of the different types of commands - streaming, transforming, generating and data processing. Pick one and move on to the next step.&lt;/p&gt;

&lt;p&gt;You can also feel free to modify the code to play around with it right now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Streaming&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;splunklib.searchcommands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;StreamingCommand&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Configuration&lt;/span&gt;


&lt;span class="nd"&gt;@Configuration&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StreamingCommand&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;


&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CustomCommand&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Reporting / Transforming&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;splunklib.searchcommands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ReportingCommand&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Configuration&lt;/span&gt;


&lt;span class="nd"&gt;@Configuration&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ReportingCommand&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nd"&gt;@Configuration&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;


&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CustomCommand&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Generating&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;splunklib.searchcommands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GeneratingCommand&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Configuration&lt;/span&gt;


&lt;span class="nd"&gt;@Configuration&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GeneratingCommand&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;


&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CustomCommand&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Eventing / Data Processing&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;splunklib.searchcommands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EventingCommand&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Configuration&lt;/span&gt;


&lt;span class="nd"&gt;@Configuration&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EventingCommand&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;


&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CustomCommand&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Tell Splunk about it
&lt;/h2&gt;

&lt;p&gt;Now how does Splunk know we made a custom command? We register it within our app with two config files - &lt;a href="https://docs.splunk.com/Documentation/Splunk/9.1.3/Admin/Commandsconf"&gt;commands.conf&lt;/a&gt; and &lt;a href="https://docs.splunk.com/Documentation/Splunk/9.1.3/Admin/Searchbnfconf"&gt;searchbnf.conf&lt;/a&gt;. Create these files in your app's default directory.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;commands.conf&lt;/code&gt; path &amp;amp; content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$SPLUNK_HOME/etc/apps/my_custom_app/default/commands.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[my_custom_command]&lt;/span&gt;
&lt;span class="py"&gt;python.version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;python3&lt;/span&gt;
&lt;span class="py"&gt;filename&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;my_custom_command.py&lt;/span&gt;
&lt;span class="py"&gt;chunked&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;searchbnf.conf&lt;/code&gt; path &amp;amp; content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$SPLUNK_HOME/etc/apps/my_custom_app/default/searchbnf.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[my_custom_command-command]&lt;/span&gt;
&lt;span class="py"&gt;syntax&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;[my_custom_command]&lt;/span&gt;
&lt;span class="py"&gt;shortdesc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;[A short description of your custom command]&lt;/span&gt;
&lt;span class="py"&gt;usage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;public&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Restart Splunk and test it
&lt;/h2&gt;

&lt;p&gt;We can now restart Splunk to apply the new configuration using this command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$SPLUNK_HOME&lt;/span&gt;/bin/splunk restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also do this directly from the UI via &lt;code&gt;Setting &amp;gt; Server Controls &amp;gt; Restart Splunk&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fY9mxAO0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://tinypic.host/images/2024/01/28/Splunk-Restart.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fY9mxAO0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://tinypic.host/images/2024/01/28/Splunk-Restart.png" alt="Splunk Restart" width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you can test it in the "Search and Reporting" app with this SPL command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;index=_internal | my_custom_command
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations! You've successfully created a custom search command in your Splunk app. Now you can enhance and modify the script based on your specific use case. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bonus&lt;/strong&gt;: You can check out the &lt;a href="https://github.com/splunk/splunk-app-examples/tree/master/custom_search_commands/python"&gt;Splunk-app-examples&lt;/a&gt; which is a treasure chest of ready-made templates and inspiration for your Splunk custom search commands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy Splunking!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>splunk</category>
    </item>
    <item>
      <title>High-level Parsing Concepts</title>
      <dc:creator>Uman Shahzad</dc:creator>
      <pubDate>Mon, 05 Feb 2024 23:27:51 +0000</pubDate>
      <link>https://dev.to/mslm_uman/high-level-parsing-concepts-4ba9</link>
      <guid>https://dev.to/mslm_uman/high-level-parsing-concepts-4ba9</guid>
      <description>&lt;p&gt;This post will teach you some general things you need to know and think about when parsing out structured content inside a buffer. It will particularly provide questions to ask and points to ponder when approaching any parsing problem, along with some real-world examples.&lt;/p&gt;

&lt;p&gt;We will not talk about any particular algorithm, e.g. those used in compilers or other sophisticated programs with large and complex parsing steps. However, all of the concepts explained here will be useful in one or way or another in any parsing context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Whole vs. Chunks
&lt;/h2&gt;

&lt;p&gt;One of the most important parameters in deciding a parsing strategy is how the input is received; is it one buffer that contains the entirety of the structure, or a partial buffer (a chunk) that gets more data over time (streaming)?&lt;/p&gt;

&lt;p&gt;When dealing with the entirety of the structure in a single buffer at once, the algorithm is usually very simple to express. You can have a simple loop that goes from start to finish in the buffer, and keep state and context data relevant to the problem updated as the loop proceeds. There is usually never a reason to backtrack in the buffer itself, since out-of-band state and context data should be correctly kept up-to-date regarding what's been parsed so far.&lt;/p&gt;

&lt;p&gt;When dealing with only chunks of the structure at a time, where chunk boundaries may occur at arbitrary points in the structure, parsing becomes significantly more difficult because the control flow is harder to express; a simple loop is usually never sufficient. However, by asking certain questions and coming up with the right solutions for your particular problem, the parse can be made a lot simpler:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is the input source?&lt;/li&gt;
&lt;li&gt;Is the input going to be retrieved in one big chunk, or in multiple fixed-sized chunks, or in multiple variable-sized chunks? And is the chunk size going to be sufficient for performing all parse steps, or will we need to buffer previous chunks until we get 1 bigger chunk that can be properly parsed?&lt;/li&gt;
&lt;li&gt;What non-buffer data (i.e. context/state) is needed to help perform a later parse step given the current chunk?&lt;/li&gt;
&lt;li&gt;How is the data encoded inside the buffer going to be output to the user after parsing?&lt;/li&gt;
&lt;li&gt;What guarantees do we have about total size? Do we know in advance, or do we need to track how much has been input so far, in order to enforce limits?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Examples
&lt;/h3&gt;

&lt;p&gt;In each example, we ask ourselves relevant questions and answer them in order to come to a reasonable parsing strategy.&lt;/p&gt;

&lt;h4&gt;
  
  
  Stream Parsing JSON
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Q&lt;/strong&gt;: What is the input source?&lt;/p&gt;

&lt;p&gt;Assume the input source to be a network socket using a streaming protocol like TCP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q&lt;/strong&gt;: What is the chunk size, and can all parsing steps succeed on a chunk of that size, or will buffering be needed?&lt;/p&gt;

&lt;p&gt;Data from the network socket will come in streams, and JSON itself contains elements of varying lengths, so a single size will not suffice for all possible entities, nor does it align itself well with the streaming input model of the socket. So, we will use whatever comes from the socket first, and if it doesn't contain enough data for 1 successful parse step, we will buffer that data and ask for more, appending to the buffer until we can successfully complete a parse step. Then we can deallocate the buffer and start with a new one for more data, until the end of the JSON representation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q&lt;/strong&gt;: What non-buffer data is needed?&lt;/p&gt;

&lt;p&gt;We need several pieces of state information. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Has the JSON document just started?&lt;/li&gt;
&lt;li&gt;Has the JSON document just ended?&lt;/li&gt;
&lt;li&gt;Have we just read in a key in an object, and are now expecting a value?&lt;/li&gt;
&lt;li&gt;Have we just read in a value and a comma, and are now expecting another key (if in an object) or a value (if in an array)?&lt;/li&gt;
&lt;li&gt;Has a new array just started?&lt;/li&gt;
&lt;li&gt;Has a new object just started?&lt;/li&gt;
&lt;li&gt;Has an array just ended?&lt;/li&gt;
&lt;li&gt;Has an object just ended?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Additionally, we need to know how deep we are in the JSON hierarchy, and whether the parent layers were arrays or objects. This is important because as we "close" an object or array, we need to know whether the new scope is within an object or array, so we can properly confirm whether the scope will be closed appropriately, and whether to expect a key or value.&lt;/p&gt;

&lt;p&gt;In other words, lots of data is needed outside of the buffer itself as we parse. We cannot ensure a fully correct parse otherwise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q&lt;/strong&gt;: How is the data encoded inside the buffer going to be output to the user after parsing?&lt;/p&gt;

&lt;p&gt;In the interest of making the least amount of assumptions about the user's desired non-buffer data format, we will only choose to output individual data types which have a 1-to-1 correspondence between JSON and the programming language used.&lt;/p&gt;

&lt;p&gt;So, if we just completed the parse for a number, and it was in floating-point format, we can use one of &lt;code&gt;f64_t&lt;/code&gt; or &lt;code&gt;f128_t&lt;/code&gt; depending upon the size of the number. If it was an unsigned number, we will output a &lt;code&gt;u64_t&lt;/code&gt;. If it was a negative number, then &lt;code&gt;s64_t&lt;/code&gt;. If a string (whether key or value), then a &lt;code&gt;str_t&lt;/code&gt;. And so on.&lt;/p&gt;

&lt;p&gt;We do not discriminate against objects or arrays; the user will have to check the current JSON parse state to figure out in what context (whether object or array) the data was found, in case they need to construct an array or object of their own format (which may be a hashtable, a linked list, or any other format) in their application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q&lt;/strong&gt;: What guarantees do we have about total size?&lt;/p&gt;

&lt;p&gt;When receiving from the network, especially if received from the open internet where anyone may send a message, malicious or otherwise, we cannot make many guarantees about the total input size.&lt;/p&gt;

&lt;p&gt;Instead, we can set internal limits, such as, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A maximum string size of 1MB.&lt;/li&gt;
&lt;li&gt;A maximum object/array hierarchy depth of 200.&lt;/li&gt;
&lt;li&gt;A maximum total document size of 5MB.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There may be more limits, and all of these limits will be configurable. So a user trying to parse trusted JSON from disk can choose to remove the document size limit completely because they may be parsing gigabytes worth of JSON. Or a user who knows that some data coming from a web request will contain strings of sizes up to 5MB can change the string size limit and the total document size limit to compensate for that use case.&lt;/p&gt;

&lt;h4&gt;
  
  
  On-Disk CSV File Parsing
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Q&lt;/strong&gt;: What is the input source?&lt;/p&gt;

&lt;p&gt;The input source is a file on a local filesystem. The entirety of the file will be loaded before parsing starts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q&lt;/strong&gt;: What is the chunk size, and can all parsing steps succeed on a chunk of that size, or will buffering be needed?&lt;/p&gt;

&lt;p&gt;Because we have the entirety of the CSV data in-memory, our "chunk" is really the entire file and so can be trivially parsed successfully by any parsing step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q&lt;/strong&gt;: What non-buffer data is needed?&lt;/p&gt;

&lt;p&gt;We can keep track of several pieces of state information, some necessary for correctness parsing and others necessary for debugging/etc. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How many total columns are expected from the header?&lt;/li&gt;
&lt;li&gt;What column are we in right now?&lt;/li&gt;
&lt;li&gt;What row are we in right now?&lt;/li&gt;
&lt;li&gt;Are we inside of a double-quoted cell?&lt;/li&gt;
&lt;li&gt;Has the header been parsed already?&lt;/li&gt;
&lt;li&gt;Did a new row just start?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Q&lt;/strong&gt;: How is the data encoded inside the buffer going to be output to the user after parsing?&lt;/p&gt;

&lt;p&gt;Because CSV only specifies data as strings, by default we will parse each cell as a buf_t. The user can then perform further parsing on the individual cell depending upon which column it was in. For examplee, it may contain a number or a boolean value which can be converted to a &lt;code&gt;s32_t&lt;/code&gt; or a &lt;code&gt;bool_t&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q&lt;/strong&gt;: What guarantees do we have about total size?&lt;/p&gt;

&lt;p&gt;We know the exact size of the full CSV file because that information is available via the filesystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structure Assumptions
&lt;/h2&gt;

&lt;p&gt;The source of data may or may not be reliable. Getting data from the local filesystem that was written by an internal system poses an entirely different parsing problem than getting data from the network sent by an arbitrary host following some protocol defined in a public IETF RFC.&lt;/p&gt;

&lt;p&gt;When receiving data for which we can make very strong guarantees regarding structure, parsing can generally avoid looking for error conditions and anomolous circumstances. But if the data comes from an untrusted arbitrary source, little to no assumption can be made about what's being received.&lt;/p&gt;

&lt;p&gt;If little assumptions can be made about the data, what to do is dependant upon the particular problem. Generally, however, it is useful to think in the shoes of an adversary who can input arbitrary data into your parsing system, sometimes fuzzy and sometimes semi-structured.&lt;/p&gt;

&lt;p&gt;When the consequence of a crash caused by an internal error in the parsing system from an unhandled case is low, it is generally acceptable to allow it and solve it iteratively, especially if the particular parsing problem is very complex, such as when parsing a programming language locally with a compiler.&lt;/p&gt;

</description>
      <category>parsing</category>
    </item>
    <item>
      <title>JWT Revokation</title>
      <dc:creator>Uman Shahzad</dc:creator>
      <pubDate>Mon, 05 Feb 2024 23:26:13 +0000</pubDate>
      <link>https://dev.to/mslm_uman/jwt-revokation-3il7</link>
      <guid>https://dev.to/mslm_uman/jwt-revokation-3il7</guid>
      <description>&lt;p&gt;Among the many criticisms given to stateless tokens, specifically JWT, the only one I ever found reasonable was that stateless tokens usually have no built-in or simple means of revokation.&lt;/p&gt;

&lt;p&gt;JWT lovers defend by claiming that a short enough expiry is enough of a revokation scheme for them. The JWT haters continue to claim that isn't a revokation scheme at all, because you're not really revoking anything when you need to revoke it.&lt;/p&gt;

&lt;p&gt;Both sides make sense to me - some application owners using JWT just want simplicity and find the JWT ecosystem wide enough to easily include a "fast" authentication scheme into their application (ignoring the fact that some of those JWT libraries literally do database lookups for each request alongside verifying the JWT statelessly, practically nullifying the performance gain!), but it's also true that they don't really have a solid revokation scheme, and an attacker who gets their hands on the wrong JWT can wreak havoc pretty quickly while your customers ask you why you can't stop them.&lt;/p&gt;

&lt;p&gt;So in that context, let's consider what an actual revokation scheme would look like, where one doesn't sacrifice the performance benefits of JWT. Disclaimer: any strong and scalable revokation scheme won't make JWTs "simple" in any sense anymore, especially because I don't know of any 1-click ecosystem solution for it yet (yes, you can probably make a business out of this). So if the reason you use JWT is for its simplicity, that'll be lost as soon as you want a strong revokation scheme and are required to build your own. Just know what you're getting into.&lt;/p&gt;

&lt;p&gt;In a nutshell and at a high-level, here's what the revokation scheme looks like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A distributed database/key-value store that allows publishing changes to subscribers/listeners/watchers/whatever-lingo-it-uses.&lt;/li&gt;
&lt;li&gt;An application that performs authentication using JWTs which can subscribe/listen/watch/etc the distributed store on a separate thread.&lt;/li&gt;
&lt;li&gt;An in-memory data structure (hashmap) that the application can use to locally store and look-up blacklisted JWTs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Engineers should already understand how this all connects. But just to detail it out:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The distributed store holds blacklisted JWTs. An admin should be able to update it easily, and the changes should propagate to all replications of that store (e.g. globally) extremely fast.&lt;/li&gt;
&lt;li&gt;Applications that do authentication with JWT will write some logic to start a separate thread upon start-up which simply subscribes/listens/watches on the appropriate channel/key/etc and each time a message comes in, runs logic to update an in-memory data structure such as a hashmap to mirror the database store's state of blacklisted JWTs. The action of subscribing/listening/watching happens through a persistent TCP connection - you don't have to make a request every second to detect updates, you get "pushed" the update by the distributed store.&lt;/li&gt;
&lt;li&gt;Authentication logic is modified so that on every request that requires authentication using JWTs, the in-memory data structure is queried to find if the request's token matches or not - this should be super fast, because the data structure is on the application's heap just like many other variables it'd work with while serving the request. If there's a match, we execute request rejection logic.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Revokation (or even reallowance) happens at the time the admin commits the update to the distributed store, so that's basically as fast as you can get as long as your revokation scheme is human-guided.&lt;/p&gt;

&lt;p&gt;The obvious downside though is the added complexity, which is why this is a bit troublesome. But as alluded to earlier, this is something that can be offered as a central service by some cloud provider or similar, with client libraries that could require 1 or 2 lines of logic to get going. There may be some authentication-focused businesses who may already be offering this.&lt;/p&gt;

</description>
      <category>jwt</category>
      <category>authentication</category>
      <category>authorization</category>
      <category>auth</category>
    </item>
    <item>
      <title>The Absolute Minimum Every Software Developer Must Know About Pointers</title>
      <dc:creator>Uman Shahzad</dc:creator>
      <pubDate>Mon, 05 Feb 2024 23:24:03 +0000</pubDate>
      <link>https://dev.to/mslm_uman/the-absolute-minimum-every-software-developer-must-know-about-pointers-2g1k</link>
      <guid>https://dev.to/mslm_uman/the-absolute-minimum-every-software-developer-must-know-about-pointers-2g1k</guid>
      <description>&lt;p&gt;The concept of pointers regularly confuses beginner programmers. But pointers are fundamental to understanding how sophisticated memory management works in programs, so their importance cannot be avoided. In this post, we will use C-like syntax as a tool to help demonstrate pointer concepts.&lt;/p&gt;

&lt;p&gt;The examples we shall encounter are simple and usually not what happens in the real world necessarily - especially the more complex examples. A C-like syntax is used only to give a taste of how the code might look like when using pointers. What is much, much more important is understanding what pointers are all about as a general concept. When you understand that, then the real-world use cases will start to look and feel obvious and easy.&lt;/p&gt;

&lt;h2&gt;
  
  
  What really is a pointer?
&lt;/h2&gt;

&lt;p&gt;On 64-bit systems (and analogously on 32-bit ones), a pointer is nothing but a 8-byte number that is supposed to be interpreted as an address in memory.&lt;/p&gt;

&lt;p&gt;When we say a pointer "points to" something, we mean that the address the pointer contains is the address of that "something" in memory.&lt;/p&gt;

&lt;p&gt;A pointer that points to a value can be "dereferenced" to get the actual memory contents that the value holds.&lt;/p&gt;

&lt;p&gt;A "dangling" pointer is a pointer that used to point to a memory location that had "valid" user-initiated data, but now that memory location is no longer "valid" for some reason or another. A memory location could become invalid if, for example, the memory gets deallocated by the application and reclaimed by the operating system. And so a pointer pointing to such a location now points to an invalid memory location, and is thus "dangling" unless it is reassigned to a valid location.&lt;/p&gt;

&lt;p&gt;A "nil" pointer is a pointer whose address value refers to an address that will never be possibly valid in the lifetime of a program. In most modern programs with a pointer concept, the &lt;code&gt;nil&lt;/code&gt; pointer always has the value &lt;code&gt;0&lt;/code&gt;, although it can technically be anything as long as the address can never be valid. In the examples in this document, we use the &lt;code&gt;0&lt;/code&gt; address as if it were usable, but only for illustration. In the real world, the &lt;code&gt;0&lt;/code&gt; address will generally not be accessible, and is also usually what all &lt;code&gt;NULL&lt;/code&gt; or &lt;code&gt;nil&lt;/code&gt; pointers have as their value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pointing to a Value
&lt;/h2&gt;

&lt;p&gt;Let us consider a pointer &lt;code&gt;p&lt;/code&gt; that points to &lt;code&gt;v&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An example illustration of how memory would look after this code runs is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ADDR    NAME    VAL
0       v       +---------+
                |    5    |
                +---------+
4       p       +---------+
                |    0    |
                +---------+
12      N/A     N/A
16      N/A     N/A
20      N/A     N/A
24      N/A     N/A
...     ...     ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;v&lt;/code&gt; is the name of a 32-bit signed number whose value is currently &lt;code&gt;5&lt;/code&gt;. It is at the very start of memory, at address &lt;code&gt;0&lt;/code&gt;. Since &lt;code&gt;v&lt;/code&gt; takes 4 bytes, that means it occupies addresses &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt; and &lt;code&gt;3&lt;/code&gt; in total. The next value after &lt;code&gt;v&lt;/code&gt; will start at address &lt;code&gt;4&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You will notice that we are incrementing addresses by 1 whenever 8 bits (or 1 byte) has passed in memory; this is how addresses are always counted - we don't increment an address when only 1 bit has passed or only after more than 1 byte has passed. Each address represents a unique byte in memory, where address &lt;code&gt;A-1&lt;/code&gt; is 1 byte before address &lt;code&gt;A&lt;/code&gt; and address &lt;code&gt;A+1&lt;/code&gt; is 1 byte ahead of address &lt;code&gt;A&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;p&lt;/code&gt; is the name of a 64-bit address whose value is currently &lt;code&gt;0&lt;/code&gt;. Since &lt;code&gt;0&lt;/code&gt; is the address of &lt;code&gt;v&lt;/code&gt;, &lt;code&gt;p&lt;/code&gt; is said to point to &lt;code&gt;v&lt;/code&gt;. Since &lt;code&gt;p&lt;/code&gt; is 64-bits long, it takes 8 bytes and therefore 8 unique address locations, specifically the addresses &lt;code&gt;4&lt;/code&gt;, &lt;code&gt;5&lt;/code&gt;, &lt;code&gt;6&lt;/code&gt;, &lt;code&gt;7&lt;/code&gt;, &lt;code&gt;8&lt;/code&gt;, &lt;code&gt;9&lt;/code&gt;, &lt;code&gt;10&lt;/code&gt; and &lt;code&gt;11&lt;/code&gt;. The next value after &lt;code&gt;p&lt;/code&gt; will start at address &lt;code&gt;12&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If we were to dereference &lt;code&gt;p&lt;/code&gt; with &lt;code&gt;*p&lt;/code&gt; while it holds address &lt;code&gt;0&lt;/code&gt;, the result of evaluating that expression would give us &lt;code&gt;5&lt;/code&gt;, which is the value found at address &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pointing to a List of Values
&lt;/h2&gt;

&lt;p&gt;If we had 3 values &lt;code&gt;v1&lt;/code&gt;, &lt;code&gt;v2&lt;/code&gt; and &lt;code&gt;v3&lt;/code&gt;, all of which are consecutive in memory and are the same length and type, we can use a pointer &lt;code&gt;p&lt;/code&gt; to point to the first value in this list of values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;v1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;v2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;52&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;v3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;53&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;ASSERT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;ASSERT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;52&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;ASSERT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;53&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the above code ran and &lt;code&gt;v1&lt;/code&gt;, &lt;code&gt;v2&lt;/code&gt; and &lt;code&gt;v3&lt;/code&gt; happened to be next to each other in memory in that order, the assertions in the code above would hold true. (Note that in C there is no such guarantee; instead, a C user would use an array type which contains these 3 values, which will tell the compiler to explicitly put the 3 values consecutively in memory. However, we do not consider array types in this section for simplicity.)&lt;/p&gt;

&lt;p&gt;Now, when &lt;code&gt;p = &amp;amp;v1&lt;/code&gt; in the above code occurs, this is an example illustration of what memory would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ADDR    NAME    VAL
0       v1      +---------+
                |    51   |
                +---------+
4       v2      +---------+
                |    52   |
                +---------+
8       v3      +---------+
                |    53   |
                +---------+
12      p       +---------+
                |    0    |
                +---------+
20      N/A     N/A
24      N/A     N/A
28      N/A     N/A
32      N/A     N/A
...     ...     ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When &lt;code&gt;*p&lt;/code&gt; is run, this is dereferencing the pointer to get the value at address &lt;code&gt;0&lt;/code&gt;. Since &lt;code&gt;p&lt;/code&gt; is specifically an &lt;code&gt;int&lt;/code&gt; pointer (note that it was declared as &lt;code&gt;int *p&lt;/code&gt; and not as &lt;code&gt;bool_t *p&lt;/code&gt; or some other type), it is assumed that the value at address &lt;code&gt;0&lt;/code&gt; is an int, so &lt;code&gt;*p&lt;/code&gt; translates into &lt;code&gt;51&lt;/code&gt;, the int value found at address &lt;code&gt;0&lt;/code&gt;. We will discuss in the "Pointer Aliasing" section what would happen if &lt;code&gt;p&lt;/code&gt; was a different pointer type but pointed to an &lt;code&gt;int&lt;/code&gt; nonetheless.&lt;/p&gt;

&lt;p&gt;When &lt;code&gt;p += 1&lt;/code&gt; occurs, since &lt;code&gt;p&lt;/code&gt; was an &lt;code&gt;int&lt;/code&gt; pointer and &lt;code&gt;int&lt;/code&gt; is 4 bytes long, it is automatically incremented by 4 bytes; the address inside &lt;code&gt;p&lt;/code&gt; is updated from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;4&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note that in C, incrementing any pointer of any type by any amount is always scaled by how long its type is. So if &lt;code&gt;p&lt;/code&gt; was a pointer to a 8-byte number instead of a 4-byte one, &lt;code&gt;p += 1&lt;/code&gt; would increment by 8 addresses rather than 4. In &lt;a href="https://mslm.io/mlang"&gt;Mlang&lt;/a&gt;, the operation is never automatically scaled by the type's length, so adding 1 to any pointer type will always explicitly add 1 address.&lt;/p&gt;

&lt;p&gt;After &lt;code&gt;p&lt;/code&gt; is incremented so that the address in it becomes &lt;code&gt;4&lt;/code&gt;, dereferencing it with &lt;code&gt;*p&lt;/code&gt; gives us the value found at address &lt;code&gt;4&lt;/code&gt; which is currently &lt;code&gt;52&lt;/code&gt;. A similar thing happens again in the next increment and dereference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aside: Pointer Aliasing
&lt;/h2&gt;

&lt;p&gt;Before continuing, as a thought experiment, consider what would happen if we had another pointer &lt;code&gt;p2&lt;/code&gt; which was declared as &lt;code&gt;bool_t *p2&lt;/code&gt;, which is a boolean pointer, as such:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;bool_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;p2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bool_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since a &lt;code&gt;bool_t&lt;/code&gt; is only 1 byte long, &lt;code&gt;*p2&lt;/code&gt; would mean to get the boolean value at the address in &lt;code&gt;p2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This can be problematic, since we did not intend to put a boolean value in &lt;code&gt;v&lt;/code&gt;. If it is done nonetheless, then only the first byte of &lt;code&gt;v&lt;/code&gt; will be retrieved and interpreted as a boolean value.&lt;/p&gt;

&lt;p&gt;This may seem troubling, but it is possible in C by force if the programmer wishes. This is rarely done in this way exactly, but if it is, the reason for doing so should be well-documented and well-reasoned, and only after considering the use of a language-level facility like union in C, which allows representing multiple different types in the same memory location safely. The details of union are out of scope for this document.&lt;/p&gt;

&lt;p&gt;Compilers may have issues performing certain optimizations if more than 1 pointer points to the same value but with different types, because less assumptions can be made about what's happening. So, they introduce the concept of a "strict" pointer aliasing rule which requires that all pointers pointing to the same memory location are of the same type, otherwise the program is considered as having undefined behavior. An exception is made for the &lt;code&gt;char *&lt;/code&gt; and &lt;code&gt;void *&lt;/code&gt; pointer types, however, which can be used to refer to the same memory location as any other pointer type, without breaking this rule.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://mslm.io/mlang"&gt;Mlang&lt;/a&gt;, no strict pointer aliasing rule exists and the associated optimizations are not made on purpose; the programmer must perform the relevant optimization manually or make it explicit to the compiler that they desire a particular optimization. In our experience, this makes translation from the language to assembly a lot more predictable. We prefer the user to have more control over the compiler than have the compiler assume it can always do better than the user. The compiler is only a tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pointing to a List of Variable-Sized Values
&lt;/h2&gt;

&lt;p&gt;Instead of numbers, consider trying to store characters in memory consecutively, which can then be interpreted together as representing a human-readable sentence.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hello"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;s&lt;/code&gt; is a pointer to a character, and when the &lt;code&gt;"Hello"&lt;/code&gt; expression is evaluated, it returns a character pointer to the start location of the string. In particular, it returns the address of the &lt;code&gt;"H"&lt;/code&gt; in &lt;code&gt;"Hello"&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ADDR    NAME    VAL
0       N/A     +---------+
                |    H    |
                |    e    |
                |    l    |
                |    l    |
                |    o    |
                |   \0    |
                +---------+
6       N/A     N/A
7       N/A     N/A
8       s       +---------+
                |    0    |
                +---------+
16      N/A     N/A
20      N/A     N/A
...     ...     ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The memory for &lt;code&gt;"Hello"&lt;/code&gt; is stored starting at address &lt;code&gt;0&lt;/code&gt;, and goes on until address &lt;code&gt;5&lt;/code&gt;. The reason this is actually 1 value higher than what you'd expect, is because in languages like C, strings declared in the source code are automatically appended with a &lt;code&gt;NUL&lt;/code&gt; byte (the &lt;code&gt;'\0'&lt;/code&gt; character), which is the &lt;code&gt;0&lt;/code&gt; value in 7-bit ASCII. We adopt strings of this format (often called "C-strings" because of their ubiquity in the C language) for this lesson.&lt;/p&gt;

&lt;p&gt;The actual pointer &lt;code&gt;s&lt;/code&gt; starts at address &lt;code&gt;8&lt;/code&gt; (see the section "Aside: Alignment" for why &lt;code&gt;s&lt;/code&gt; doesn't start at address &lt;code&gt;6&lt;/code&gt;, which is unused in this example). The value it contains is address &lt;code&gt;0&lt;/code&gt;, which points to the &lt;code&gt;"H"&lt;/code&gt; character.&lt;/p&gt;

&lt;p&gt;Now, in order to access the remaining characters in the string, we can simply increment &lt;code&gt;s&lt;/code&gt; by &lt;code&gt;1&lt;/code&gt;, access the character, and repeat, until we reach the special NUL byte character &lt;code&gt;'\0'&lt;/code&gt;, which indicates that we have reached the end of the string. Indeed, this methodology is exactly the technique used to get the total length of C-strings, because there is no other way otherwise.&lt;/p&gt;

&lt;p&gt;Now that we understand how to point to strings, it's natural that as our programs have more use cases, they will require multiple strings that are somehow related, and must be stored "together" in some way, but still remain separate strings.&lt;/p&gt;

&lt;p&gt;One methodology for doing this is to store all the strings that we feel are related next to each other in memory, just as we did with numbers:&lt;/p&gt;

&lt;p&gt;Here is one weird trick one can pull to achieve this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;char *s = "Hi\0Bye";
ADDR    NAME    VAL
0       N/A     +---------+
                |    H    |
                |    i    |
                |   \0    |
                +---------+
3       N/A     +---------+
                |    B    |
                |    y    |
                |    e    |
                |   \0    |
                +---------+
7       N/A     N/A
8       s       +---------+
                |    0    |
                +---------+
16      N/A     N/A
20      N/A     N/A
24      N/A     N/A
28      N/A     N/A
...     ...     ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we manually put a &lt;code&gt;NUL&lt;/code&gt; byte between &lt;code&gt;"Hi"&lt;/code&gt; and &lt;code&gt;"Bye"&lt;/code&gt;, making them look like 2 C-strings in memory, and having a pointer &lt;code&gt;s&lt;/code&gt; point to &lt;code&gt;"H"&lt;/code&gt;. &lt;code&gt;s&lt;/code&gt; can be used to iterate through the "list of strings" in this way.&lt;/p&gt;

&lt;p&gt;This is obviously problematic; as our string quantities and sizes increase, this strategy becomes too problematic in practice. Even more, what happens if you wanted to dynamically grow the size of one of these strings? For example, what if &lt;code&gt;"Hi"&lt;/code&gt; needs to be converted to &lt;code&gt;"Hi, brother"&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;So instead, let us consider a more general format. Instead of requiring that the string content itself gets stored next to each other in memory, we instead store a list of character pointers together in memory, and have them each point to one unique string which could be stored anywhere and managed separately.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hi"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Bye"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ADDR    NAME    VAL
0       N/A     +---------+
                |    H    |
                |    i    |
                |   \0    |
                +---------+
8       s1      +---------+
                |    0    |
                +---------+
16      s2      +---------+
                |   44    |
                +---------+
24      p       +---------+
                |    8    |
                +---------+
32      N/A     N/A
36      N/A     N/A
40      N/A     N/A
44      N/A     +---------+
                |    B    |
                |    y    |
                |    e    |
                |   \0    |
                +---------+
48      N/A     N/A
52      N/A     N/A
...     ...     ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we assume that &lt;code&gt;s1&lt;/code&gt; and &lt;code&gt;s2&lt;/code&gt; are stored contiguously in memory just as if they were in an array together. &lt;code&gt;p&lt;/code&gt; is stored after them. The two strings, &lt;code&gt;"Hi"&lt;/code&gt; and &lt;code&gt;"Bye"&lt;/code&gt;, are stored far apart from each other. &lt;code&gt;s1&lt;/code&gt; and &lt;code&gt;s2&lt;/code&gt; contain the addresses of these two strings, and &lt;code&gt;p&lt;/code&gt; points to &lt;code&gt;s1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What &lt;code&gt;p&lt;/code&gt; essentially is now is a "pointer to an array of character pointers". Each of the character pointers (&lt;code&gt;s1&lt;/code&gt; and &lt;code&gt;s2&lt;/code&gt;) are themselves a "pointer to a character array". Using &lt;code&gt;p&lt;/code&gt;, we can access both &lt;code&gt;"Hi"&lt;/code&gt; and &lt;code&gt;"Bye"&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// s will be equal to `s1`.&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;ASSERT_EQ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sc"&gt;'H'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;ASSERT_EQ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sc"&gt;'i'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;ASSERT_EQ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sc"&gt;'\0'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// s will be equal to `s2`.&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;ASSERT_EQ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sc"&gt;'B'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;ASSERT_EQ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sc"&gt;'y'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;ASSERT_EQ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sc"&gt;'e'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;ASSERT_EQ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sc"&gt;'\0'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;s&lt;/code&gt; is a character pointer that is being used to reference &lt;code&gt;s1&lt;/code&gt; and &lt;code&gt;s2&lt;/code&gt; one-by-one. When it first points to &lt;code&gt;s1&lt;/code&gt;, it is dereferenced using an offset of &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;2&lt;/code&gt; to assert that the value at each address is &lt;code&gt;'H'&lt;/code&gt;, &lt;code&gt;'i'&lt;/code&gt; and &lt;code&gt;'\0'&lt;/code&gt; respectively.&lt;/p&gt;

&lt;p&gt;The same is then done when &lt;code&gt;s&lt;/code&gt; is changed to point to &lt;code&gt;s2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note that the syntax of the form &lt;code&gt;*(&amp;lt;ptr&amp;gt;+&amp;lt;number&amp;gt;)&lt;/code&gt;, such as &lt;code&gt;*(s+1)&lt;/code&gt;, is the longer form version of what is found in C as &lt;code&gt;s[1]&lt;/code&gt;. The expression &lt;code&gt;s[1]&lt;/code&gt; actually expands into &lt;code&gt;*(s+1)&lt;/code&gt;, because it is doing exactly that: &lt;code&gt;1&lt;/code&gt; is being added to &lt;code&gt;s&lt;/code&gt; (since &lt;code&gt;s&lt;/code&gt; is a character pointer, the actual address gets increased by 1 only) and then the resulting address is dereferenced to get the value stored at that address, which is a character in one of our strings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aside: Alignment
&lt;/h2&gt;

&lt;p&gt;Consider having 3 numbers in memory, two 8-bit numbers and one 32-bit number, layed out as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ADDR    NAME    VAL
0       N/A     +---------+
                |    5    |
                +---------+
1       N/A     +---------+
                |    9    |
                +---------+
2       N/A     +---------+
                |   999   |
                +---------+
5       N/A     N/A
8       N/A     N/A
12      N/A     N/A
16      N/A     N/A
...     ...     ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When retrieving the 8-bit number 5 at address &lt;code&gt;0&lt;/code&gt;, or the 8-bit number 9 at address &lt;code&gt;1&lt;/code&gt;, everything is alright and works as expected when using assembly instructions appropriate for that size of access.&lt;/p&gt;

&lt;p&gt;But, depending upon the CPU ISA, trying to access the 32-bit number at address &lt;code&gt;2&lt;/code&gt; can cause a program to crash, or do the load slower than the other loads, or lose load atomicity. If the number was "aligned", this would not happen.&lt;/p&gt;

&lt;p&gt;A value is "aligned" in memory if it is stored starting at an address that is divisible by some constant, where that constant is usually equal to the size of the value in bytes. If that is indeed the constant in question, we say that the value is "naturally aligned", or has "natural alignment".&lt;/p&gt;

&lt;p&gt;So, the reason why accessing the first two 8-bit numbers works is because their size in bytes is 1, and both addresses &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt; are considered divisible by 1. They are therefore naturally aligned. The reason accessing the 32-bit number fails or is slow or loses atomicity is because its size in bytes is 4, and 2 is not divisible by 4, so it is unaligned. Valid addresses would be, for example, &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;4&lt;/code&gt;, &lt;code&gt;8&lt;/code&gt;, &lt;code&gt;12&lt;/code&gt;, &lt;code&gt;16&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;When a value is thus naturally aligned, by aligning it to an address that is divisible by its size in bytes, no issues will occur.&lt;/p&gt;

&lt;p&gt;The reason for this seeming anomaly is a detail of how CPUs and memory chips work, and is out of scope for this document: just understand that it is required at the hardware level, so in software, we make sure to align our values.&lt;/p&gt;

&lt;p&gt;Because of this, if we had a structure that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;u8_t&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;u8_t&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;u32_t&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The correct memory layout would look like this after taking alignment into account:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ADDR    NAME    VAL
0       a       +---------+ &amp;lt;---+ start of struct
                |    5    |     |
                +---------+     |
1       b       +---------+     |
                |    9    |     |
                +---------+     |
2       N/A     N/A             |
3       N/A     N/A             |
4       c       +---------+     |
                |   999   |     |
                +---------+ &amp;lt;---+ end of struct
8       N/A     N/A
12      N/A     N/A
16      N/A     N/A
...     ...     ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We say that addresses &lt;code&gt;2&lt;/code&gt; and &lt;code&gt;3&lt;/code&gt; (i.e. the two extra bytes between &lt;code&gt;b&lt;/code&gt; and &lt;code&gt;c&lt;/code&gt;) are "padding" bytes - the compiler will automatically add this padding when the structure is used anywhere.&lt;/p&gt;

&lt;p&gt;On x64 systems, the program will not crash if values are unaligned, but access will be costlier and atomicity is not guaranteed any longer. In some cases, an engineer may make the decision that these costs are worth paying in order to avoid adding padding.&lt;/p&gt;

&lt;p&gt;For example, if the engineer is faced with a use case where memory usage is the costliest factor, and losing atomicity and having slightly slower accesses is worth the trade, then the compiler can be told to purposely not add padding to achieve alignment.&lt;/p&gt;

&lt;p&gt;Obviously, it is the default to always align values, whether on the heap, stack or anywhere in memory. But say, for example, you have a system that stores millions of the following structures in memory, but accesses them very infrequently and always in a single-threaded fashion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;u8_t&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="c1"&gt;// 1 byte&lt;/span&gt;
    &lt;span class="n"&gt;u64_t&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// 8 bytes&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;              &lt;span class="c1"&gt;// = 9 bytes total?&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;u64_t&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// 8 bytes&lt;/span&gt;
    &lt;span class="n"&gt;u8_t&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="c1"&gt;// 1 byte&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;              &lt;span class="c1"&gt;// = 9 bytes total?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If alignment is required, then both structures will consume 16 bytes of memory; structure &lt;code&gt;A&lt;/code&gt; will need an extra 7 bytes between &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt;, and structure &lt;code&gt;B&lt;/code&gt; will add an extra 7 after &lt;code&gt;b&lt;/code&gt; to allow other values that surround structure &lt;code&gt;B&lt;/code&gt; to be more easily aligned themselves.&lt;/p&gt;

&lt;p&gt;If alignment is turned off for both structures, then both take 9 bytes and look in memory exactly as they're written in the code. However, note that values in memory which surround instances of structure &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; will still have to be aligned themselves (unless they too were allowed to be unaligned).&lt;/p&gt;

&lt;p&gt;The engineer faced with this dilemma in such a memory-intensive system may opt for allowing these structures to be unaligned, thus saving 7 bytes per structure, which is a 43.75% memory savings - a big amount if we're talking about having gigabytes worth of these structures! If 20 GiB is used by these structures when aligned, the unaligned versions will consume 11.25 GiB instead.&lt;/p&gt;

</description>
      <category>c</category>
      <category>pointers</category>
      <category>memory</category>
    </item>
    <item>
      <title>Oxylabs Go SDK</title>
      <dc:creator>Uman Shahzad</dc:creator>
      <pubDate>Mon, 05 Feb 2024 09:22:16 +0000</pubDate>
      <link>https://dev.to/mslm_uman/oxylabs-go-sdk-b7e</link>
      <guid>https://dev.to/mslm_uman/oxylabs-go-sdk-b7e</guid>
      <description>&lt;p&gt;Hey everyone! We've created an Oxylabs Go SDK that'll allow users to more easily utilize the Oxylabs SERP APIs (and more later) via a Golang library.&lt;/p&gt;

&lt;p&gt;You can find it here: &lt;a href="https://github.com/mslmio/oxylabs-sdk-go"&gt;https://github.com/mslmio/oxylabs-sdk-go&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is just an MVP and we'll be working on improving it over time with more features.&lt;/p&gt;

&lt;p&gt;Would appreciate if Oxylabs users could try it out and give their feedback so we can start addressing it and improving the SDK.&lt;/p&gt;

&lt;p&gt;Here's a quick start example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/mslmio/oxylabs-sdk-go/serp"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Set your Oxylabs API Credentials.&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"username"&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"password"&lt;/span&gt;

    &lt;span class="c"&gt;// Initialize the SERP realtime client with your credentials.&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;serp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Use `google_search` as a source to scrape Google with adidas as a query.&lt;/span&gt;
    &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ScrapeGoogleSearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"adidas"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Results: %+v&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works with both the real-time and async integration methods and makes it especially easy to use the latter method which is otherwise quite tedious.&lt;/p&gt;

&lt;p&gt;Please see detailed documentation at &lt;a href="https://pkg.go.dev/github.com/mslmio/oxylabs-sdk-go"&gt;https://pkg.go.dev/github.com/mslmio/oxylabs-sdk-go&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source code is at github.com/mslmio/oxylabs-sdk-go&lt;/p&gt;

&lt;p&gt;Thank you!&lt;/p&gt;

</description>
      <category>oxylabs</category>
      <category>go</category>
      <category>news</category>
      <category>api</category>
    </item>
  </channel>
</rss>
