<?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: Ian Jacobs</title>
    <description>The latest articles on DEV Community by Ian Jacobs (@ijacobscpa).</description>
    <link>https://dev.to/ijacobscpa</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%2F1154307%2F61b18fb8-44dd-48ac-b7f7-a4c64ab54174.jpg</url>
      <title>DEV Community: Ian Jacobs</title>
      <link>https://dev.to/ijacobscpa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ijacobscpa"/>
    <language>en</language>
    <item>
      <title>Automatic Function Redirecting: Navigating Dynamic Code Optimization in GCC</title>
      <dc:creator>Ian Jacobs</dc:creator>
      <pubDate>Wed, 29 Nov 2023 17:44:09 +0000</pubDate>
      <link>https://dev.to/ijacobscpa/automatic-function-redirecting-navigating-dynamic-code-optimization-in-gcc-4cpl</link>
      <guid>https://dev.to/ijacobscpa/automatic-function-redirecting-navigating-dynamic-code-optimization-in-gcc-4cpl</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;In this blog post, I will be explaining the usage of indirect functions (or ifunc) and how they work to optimize code for the AARCH64 platform. This is a project for my software portability and optimization class where I am going to present a design implementation for an ifunc option when compiling with GCC. &lt;/p&gt;




&lt;h2&gt;
  
  
  PART-1: ifunc and its Intermediate Representation
&lt;/h2&gt;

&lt;p&gt;To test ifunc usage in a program I used an "autoifunc" script that creates a function redirect scheme for ARM64 scalar vectorization instructions &lt;a href="https://developer.arm.com/Architectures/Scalable%20Vector%20Extensions"&gt;(SVE)&lt;/a&gt; and regular ARM Advanced SIMD instructions &lt;a href="https://community.arm.com/support-forums/f/architectures-and-processors-forum/7028/asimd-multiply-accumulate-instruction"&gt;(ASIMD)&lt;/a&gt; before being compiled by GCC.&lt;/p&gt;

&lt;p&gt;This script checks if a c-source file is vectorizable while using either SVE or SVE2. It then rewrites the functions for SVE and ASMID and creates a resolver function for processing at run time. &lt;/p&gt;

&lt;p&gt;For testing this script I've used a program that adjusts the RGB values for a provided image which demonstrates this effect with one of the separated functions (in its own C file, referred to as function.c).&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="cm"&gt;/*

adjust_channels :: adjust red/green/blue colour channels in an image

The function returns an adjusted image in the original location.

Copyright (C)2022 Seneca College of Applied Arts and Technology
Written by Chris Tyler
Distributed under the terms of the GNU GPL v2

*/&lt;/span&gt;

&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdint.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="c1"&gt;//----Naive implementation in C&lt;/span&gt;

&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;sys/param.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;adjust_channels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;unsigned&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;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;red_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;green_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;blue_factor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&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="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;x_size&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;y_size&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="n"&gt;i&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="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MIN&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;   &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;red_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&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="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MIN&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&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="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;blue_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&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="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MIN&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&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="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;green_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;);&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;After running the program through the script it produces a descriptive/verbose explanation of its function redirecting process and is similar to what was described earlier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scripts/autoifunc &lt;span class="k"&gt;function&lt;/span&gt;.c

&lt;span class="k"&gt;*&lt;/span&gt; Auto-ifunc Tool v 0.001
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Input file: &lt;span class="s1"&gt;'function.c'&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Input file does appear to contain C source.
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Vectorization using SVE/SVE2 is being applied.
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; SVE2 optimizations are basically the same as the SVE optimizations, skipping.
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Compiling input file to assembly to get &lt;span class="k"&gt;function &lt;/span&gt;names.
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Function &lt;span class="c"&gt;#1: adjust_channels&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Writing output file.
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Output file function_ifunc.c has been created. Use this &lt;span class="k"&gt;in &lt;/span&gt;place of &lt;span class="k"&gt;function&lt;/span&gt;.c &lt;span class="k"&gt;in &lt;/span&gt;your buld.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the function.c (now function_ifunc.c) file after being run through the autoifunc script:&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="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;sys/auxv.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;adjust_channels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;unsigned&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;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;red_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;green_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;blue_factor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;    
&lt;span class="n"&gt;_attribute__&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt; &lt;span class="n"&gt;ifunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"adjust_channels__resolver"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="cp"&gt;#pragma GCC target "arch=armv8-a+sve"
&lt;/span&gt;&lt;span class="cm"&gt;/*

adjust_channels__sve :: adjust red/green/blue colour 
channels in an image

The function returns an adjusted image in the original location.

Copyright (C)2022 Seneca College of Applied Arts and Technology
Written by Chris Tyler
Distributed under the terms of the GNU GPL v2

*/&lt;/span&gt;

&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdint.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="c1"&gt;// -------------------------------------Naive implementation in C&lt;/span&gt;

&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;sys/param.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;adjust_channels__sve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;unsigned&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;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;red_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;green_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;blue_factor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&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="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;x_size&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;y_size&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="n"&gt;i&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="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MIN&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;   &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;red_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&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="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MIN&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&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="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;blue_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&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="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MIN&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&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="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;green_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="cp"&gt;#pragma GCC target "arch=armv8-a"
&lt;/span&gt;&lt;span class="cm"&gt;/*

adjust_channels__asimd :: adjust red/green/blue colour 
channels in an image

The function returns an adjusted image in the original location.

Copyright (C)2022 Seneca College of Applied Arts and Technology
Written by Chris Tyler
Distributed under the terms of the GNU GPL v2

*/&lt;/span&gt;

&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdint.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="c1"&gt;// ----------------------------------Naive implementation in C&lt;/span&gt;

&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;sys/param.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;adjust_channels__asimd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;unsigned&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;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;red_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;green_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;blue_factor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&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="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;x_size&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;y_size&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="n"&gt;i&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="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MIN&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;   &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;red_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&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="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MIN&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&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="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;blue_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&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="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MIN&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&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="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;green_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;void&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;adjust_channels__resolver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;hwcaps&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getauxval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AT_HWCAP&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;hwcaps2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getauxval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AT_HWCAP2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


 &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hwcaps&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;HWCAP_SVE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;adjust_channels__sve&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;adjust_channels__asimd&lt;/span&gt;&lt;span class="p"&gt;;&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;As can be seen, the function has been broken down into 3 different components including a redirect function with an attribute value for a resolver function below:&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;void&lt;/span&gt; &lt;span class="nf"&gt;adjust_channels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;unsigned&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;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;red_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;green_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;blue_factor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;    
 &lt;span class="n"&gt;_attribute__&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt; &lt;span class="n"&gt;ifunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"adjust_channels__resolver"&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;Next are the 2 remade functions for each variant's optimization where each function's name has been updated to indicate which method is being used for that implementation and to provide the resolver function with a way to call the specific remade function.&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;void&lt;/span&gt; &lt;span class="nf"&gt;adjust_channels__sve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;unsigned&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;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;red_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;green_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;blue_factor&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;and&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;void&lt;/span&gt; &lt;span class="nf"&gt;adjust_channels__asimd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;unsigned&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;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;red_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;green_factor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;blue_factor&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;In addition, there is the resolver function handling at the bottom which seems to get the current optimization strategy and choose the correct version of the function to work with.&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;static&lt;/span&gt; &lt;span class="nf"&gt;void&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;adjust_channels__resolver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;hwcaps&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getauxval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AT_HWCAP&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;hwcaps2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getauxval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AT_HWCAP2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


 &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hwcaps&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;HWCAP_SVE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;adjust_channels__sve&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;adjust_channels__asimd&lt;/span&gt;&lt;span class="p"&gt;;&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;This process is essentially what redirect functioning (ifunc) is doing.&lt;/p&gt;

&lt;p&gt;To analyze the compilation process for this I then compiled the new function_ifunc.c into an intermediate representation using &lt;a href="https://gcc.gnu.org/onlinedocs/gccint/GIMPLE.html"&gt;GIMPLE&lt;/a&gt; which dumps the compiler's intermediate interpretation of the code in a readable format that the compiler will then do optimizations on. &lt;/p&gt;

&lt;p&gt;To do so I used the compiler option &lt;code&gt;-fdump-tree-gimple&lt;/code&gt; with GCC to get the intermediate code. &lt;/p&gt;

&lt;p&gt;The differences between the two different indirect functions are minimal and come down to styling and variable names. &lt;/p&gt;

&lt;p&gt;A snippet of the resolver function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_attribute__((target ("arch=armv8-a+sve", "arch=armv8-a")))
void * adjust_channels__resolver ()
{
  void * D.5656;
  long int hwcaps;
  long int hwcaps2;

  # DEBUG BEGIN_STMT
  _1 = getauxval (16);
  hwcaps = (long int) _1;
  # DEBUG BEGIN_STMT
  _2 = getauxval (26);
  hwcaps2 = (long int) _2;
  # DEBUG BEGIN_STMT
  _3 = hwcaps &amp;amp; 4194304;
  if (_3 != 0) goto &amp;lt;D.5654&amp;gt;; else goto &amp;lt;D.5655&amp;gt;;
  &amp;lt;D.5654&amp;gt;:
  ...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As can be seen, the resolver function has morphed into this new intermediary function that handles each runtime compilation with the appropriate function just as it was described in the previous explanation.  &lt;/p&gt;

&lt;p&gt;Snippet from __sve function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;__attribute__((target ("arch=armv8-a+sve")))
void adjust_channels__sve (unsigned char * image, int x_size, int y_size, float red_factor, float green_factor, float blue_factor)
{
  unsigned char iftmp.0;
  unsigned char iftmp.1;
  unsigned char iftmp.2;

  # DEBUG BEGIN_STMT
  {
    int i;

    # DEBUG BEGIN_STMT
    i = 0;
    goto &amp;lt;D.5634&amp;gt;;
    &amp;lt;D.5633&amp;gt;:
    # DEBUG BEGIN_STMT
    _1 = (sizetype) i;
    _2 = image + _1;
    _3 = *_2;
    _4 = (float) _3;
    _5 = red_factor * _4;
    if (_5 &amp;lt; 2.55e+2) goto &amp;lt;D.5659&amp;gt;; else goto &amp;lt;D.5660&amp;gt;;
    &amp;lt;D.5659&amp;gt;:
    _6 = (sizetype) i;
    _7 = image + _6;
    _8 = *_7;
    _9 = (float) _8;
    _10 = red_factor * _9;
    iftmp.0 = (unsigned char) _10;
    goto &amp;lt;D.5661&amp;gt;;
    &amp;lt;D.5660&amp;gt;:
    iftmp.0 = 255;
    &amp;lt;D.5661&amp;gt;:
    _11 = (sizetype) i;
    _12 = image + _11;
    *_12 = iftmp.0;
    # DEBUG BEGIN_STMT
    _13 = (sizetype) i;
    _14 = _13 + 1;
    _15 = image + _14;
    _16 = *_15;
    _17 = (float) _16;
    _18 = blue_factor * _17;
    if (_18 &amp;lt; 2.55e+2) goto &amp;lt;D.5663&amp;gt;; else goto &amp;lt;D.5664&amp;gt;;
    &amp;lt;D.5663&amp;gt;:
    _19 = (sizetype) i;
    _20 = _19 + 1;
    _21 = image + _20;
    _22 = *_21;
    _23 = (float) _22;
    _24 = blue_factor * _23;
    iftmp.1 = (unsigned char) _24;
    goto &amp;lt;D.5665&amp;gt;;
    &amp;lt;D.5664&amp;gt;:
    iftmp.1 = 255;
    &amp;lt;D.5665&amp;gt;:
    _25 = (sizetype) i;
    _26 = _25 + 1;
    _27 = image + _26;
    *_27 = iftmp.1;
    ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Above is the __sve function that includes the _atttribute(target("arch=armv8-a+sve"))  at the function declaration that was the &lt;code&gt;#pragma GCC target "arch=armv8-a+sve"&lt;/code&gt; from the original. The code now is meant to be a readable explanation before optimizations are made.&lt;/p&gt;

&lt;p&gt;Snippet from __asmid function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;__attribute__((target ("arch=armv8-a+sve")))
void adjust_channels__sve (unsigned char * image, int x_size, int y_size, float red_factor, float green_factor, float blue_factor)
{
  unsigned char iftmp.0;
  unsigned char iftmp.1;
  unsigned char iftmp.2;

  # DEBUG BEGIN_STMT
  {
    int i;

    # DEBUG BEGIN_STMT
    i = 0;
    goto &amp;lt;D.5634&amp;gt;;
    &amp;lt;D.5633&amp;gt;:
    # DEBUG BEGIN_STMT
    _1 = (sizetype) i;
    _2 = image + _1;
    _3 = *_2;
    _4 = (float) _3;
    _5 = red_factor * _4;
    if (_5 &amp;lt; 2.55e+2) goto &amp;lt;D.5659&amp;gt;; else goto &amp;lt;D.5660&amp;gt;;
    &amp;lt;D.5659&amp;gt;:
    _6 = (sizetype) i;
    _7 = image + _6;
    _8 = *_7;
    _9 = (float) _8;
    _10 = red_factor * _9;
    iftmp.0 = (unsigned char) _10;
    goto &amp;lt;D.5661&amp;gt;;
    &amp;lt;D.5660&amp;gt;:
    iftmp.0 = 255;
    &amp;lt;D.5661&amp;gt;:
    _11 = (sizetype) i;
    _12 = image + _11;
    *_12 = iftmp.0;
    # DEBUG BEGIN_STMT
    _13 = (sizetype) i;
    _14 = _13 + 1;
    _15 = image + _14;
    _16 = *_15;
    _17 = (float) _16;
    _18 = blue_factor * _17;
    if (_18 &amp;lt; 2.55e+2) goto &amp;lt;D.5663&amp;gt;; else goto &amp;lt;D.5664&amp;gt;;
    &amp;lt;D.5663&amp;gt;:
    _19 = (sizetype) i;
    _20 = _19 + 1;
    _21 = image + _20;
    _22 = *_21;
    _23 = (float) _22;
    _24 = blue_factor * _23;
    iftmp.1 = (unsigned char) _24;
    goto &amp;lt;D.5665&amp;gt;;
    &amp;lt;D.5664&amp;gt;:
    iftmp.1 = 255;
    &amp;lt;D.5665&amp;gt;:
    _25 = (sizetype) i;
    _26 = _25 + 1;
    _27 = image + _26;
    *_27 = iftmp.1;
    ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just like the previous function, it includes the target attribute and looks very similar to the other GIMPLE example except for the different function/location calls.&lt;/p&gt;

&lt;p&gt;It seems that the GIMPLE code at this point hasn't gone through any vectorization or any optimizations as the code still contains loops (in the form of goto) and scalar operations, as well as math operations which vectorization would attempt to optimize at the highest optimization level meaning that this current implementation in GIMPLE doesn't apply vectorization yet.&lt;/p&gt;

&lt;p&gt;If we were to get the GIMPLE representation of function.c it would look like just one of the two different functions and thus it can be seen that the compiler at this stage is performing &lt;a href="https://gcc.gnu.org/wiki/LinkTimeOptimization"&gt;Link Time Optimizations&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So with that, the process of converting &lt;code&gt;function.c&lt;/code&gt; into &lt;code&gt;function_ifunc.c&lt;/code&gt; is the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Choose a specific architecture variant and extension to use optimizations from.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Decide which parts of a program are vectorizable and determine which functions should be remade into an ifunc variant.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create named versions of each of the chose functions for different architecture variant optimizations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a resolver function that uses the correct function during runtime.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a prototype "driver" function that the resolver function can load the correct auto-vectorization function into (the original function as a prototype in function_ifunc.c).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These steps are how indirect functions are created and are important to note for the next part of this blog where I talk about a theoretical design for an ifunc feature in GCC.&lt;/p&gt;




&lt;h2&gt;
  
  
  PART 2: Designing ifunc for GCC
&lt;/h2&gt;

&lt;p&gt;For the next part of this blog, I want to discuss how an auto-ifunc feature could be added to GCC to be usable by any user for compilation. &lt;/p&gt;

&lt;h3&gt;
  
  
  Command Line Argument
&lt;/h3&gt;

&lt;p&gt;Like any of the many commands that can be used in GCC enabling it would come in the form of a command line argument. For example, the option could take the name &lt;code&gt;-fauto-ifunc&lt;/code&gt;. The 'f' in the function is used for other arguments in GCC to denote that whatever follows it is a flag (more info &lt;a href="https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html"&gt;here&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Using this flag would then enable the automatic ifunc capability during compilation and looks like a good name for the feature to be called from GCC.&lt;/p&gt;

&lt;h3&gt;
  
  
  Specifying Architecture
&lt;/h3&gt;

&lt;p&gt;To facilitate this the target architecture could be specified, in a &lt;code&gt;-march=[base]+[ext1]+[ext2]...&lt;/code&gt; where m at the start, in this case, is the mode flag used in other GCC flags that deal with mode (again more info about &lt;code&gt;-m&lt;/code&gt; in GCC can be found &lt;a href="https://gcc.gnu.org/onlinedocs/gccint/Standard-Names.html"&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;For example, the argument &lt;code&gt;-march=armv8-a+sve&lt;/code&gt; would be used to specify aarch64 armv8-a type architecture variant with the SVE extension.&lt;/p&gt;

&lt;p&gt;The base architecture in this case would need to be mandatory but the additional extensions can be chosen to be added.&lt;/p&gt;

&lt;p&gt;With this implementation, there will need to be a lot of constraints that need to be added for the architecture variants for the resulting program to be runnable. &lt;/p&gt;

&lt;p&gt;These constraints would include:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Compatibility:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Making sure that these architecture variants are compatible with each other so that GCC doesn't combine incompatible features or instructions into a single executable. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Handling mutually exclusive variants (32-bit vs 64-bit)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If specifying specific instruction set extensions (e.g., SIMD), ensure that the selected extensions are compatible with each other.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Making sure that the compiler version supports the specified architecture variant &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Consistency:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ensure that the selected variants share common features so that there is no unpredictable behavior.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Library Consistency in the program by checking if the libraries that are used in the program are compatible with the specified architecture variants.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the compilation is for a different architecture than the host, ensure that cross-compilation is set up correctly, and the target architecture is supported.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are some of the main constraints that would need to be applied for the architecture variants. There are more that would need to be handled including things like runtime detection, but with proper testing and documentation in the source code, I think that this is the best solution if the constraints can all be accounted for.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Specifying Functions
&lt;/h3&gt;

&lt;p&gt;The auto-ifunc script demonstrated at the beginning of the blog shows that the script works on a per-function basis. With this in mind when adding this to GCC the names of the functions in which automatic ifunc capability should be applied.&lt;/p&gt;

&lt;p&gt;I believe that a user should have a choice as to whether they should specify specific functions or have the auto-ifunc automatically detect functions. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User-specified Functions:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This could come in the form of another extended initial argument &lt;code&gt;-fauto-ifunc-functions=[function1],[function2],...&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;For example from part 1: &lt;code&gt;-fauto-ifunc-functions=adjust_channels&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In the source code, these specific functions to be targeted will be added as &lt;code&gt;#pragma&lt;/code&gt; statements.&lt;/p&gt;

&lt;p&gt;This flag would be optional and if not provided the &lt;code&gt;-fauto-ifunc&lt;/code&gt; will need to auto-select functions based on specified selection criteria provided by the user.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automatic Function Selection &amp;amp; Specifying Selection Criteria&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This option would allow a user to specify which criteria should be used when automatically selecting functions. For example, using the criteria terms that could be specified would be: "vectorizable", "complexity", or "execution-frequency". would have the script check each function for that compatibility. &lt;/p&gt;

&lt;p&gt;To add specific criteria you could specify another default argument &lt;code&gt;-fauto-ifunc-criteria=[criteria]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;An example from part 1 would be &lt;code&gt;-fauto-ifunc-criteria=vectorizable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This argument would be optional and have a default value that would be applied if not used. This default value should be a balance between the main criteria; targeting functions that benefit from multiple implementations based on the different architectures provided (either by default or through the &lt;code&gt;-march=[arch]&lt;/code&gt; mode flag).&lt;/p&gt;

&lt;p&gt;Allowing for both user-specified and automatically selected functions would allow for more flexibility and accessibility to both advanced and novice users which in my opinion is the most effective when adding this option to GCC.&lt;/p&gt;

&lt;h3&gt;
  
  
  Diagnostics
&lt;/h3&gt;

&lt;p&gt;When running the &lt;code&gt;-fauto-ifunc&lt;/code&gt; option in GCC the user should be fully informed of the selected architecture and its variants, the name of each function that will be processed, and any potential issues that arise in attempting to run this command.&lt;/p&gt;

&lt;p&gt;An option should be included to display a more verbose diagnostic message (something like &lt;code&gt;-fauto-ifunc-verbose&lt;/code&gt;) and forgoing them completely (with something like &lt;code&gt;-fauto-ifunc-quiet&lt;/code&gt;)&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;I believe that the process I have presented here if implemented as described would be a good way to add automatic indirect function creation to GCC as it goes through the constraints and user-level control over how the option could be used seamlessly with GCC. &lt;/p&gt;

&lt;p&gt;There exist many more considerations that need to be reviewed including its many interactions with existing GCC options and its effect on the source code when used but I believe the current theoretical implementation works well for this feature. &lt;/p&gt;

</description>
      <category>spo600</category>
      <category>architecture</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
    <item>
      <title>Building GCC on Different Architectures: A Study of Cross-Compilation</title>
      <dc:creator>Ian Jacobs</dc:creator>
      <pubDate>Mon, 30 Oct 2023 01:56:09 +0000</pubDate>
      <link>https://dev.to/ijacobscpa/building-gcc-on-different-architectures-a-study-of-cross-compilation-2262</link>
      <guid>https://dev.to/ijacobscpa/building-gcc-on-different-architectures-a-study-of-cross-compilation-2262</guid>
      <description>&lt;p&gt;In this blog post, for my software optimization and portability course, I will go over the process of installing GCC on two distinct architectures x86_64 and AArch64. I will go over my process of installation for each and show them working as intended.&lt;/p&gt;

&lt;p&gt;I worked on two Linux environments with x86 and AArch64 architecture specifically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building GCC for x86_64
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Obtaining the Source Code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, I cloned the GCC git repo from &lt;a href="https://gcc.gnu.org/git/gcc.git"&gt;https://gcc.gnu.org/git/gcc.git&lt;/a&gt;.&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;$ &lt;/span&gt;git clone https://gcc.gnu.org/git/gcc.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This step took a couple of minutes as there were a lot of individual files to download&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating a Build Directory&lt;/strong&gt;: &lt;/p&gt;

&lt;p&gt;I then created a new directory outside the source directory where I would have GCC installed and gave it an appropriate name.&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;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;x86_64_gcc_install
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;x86_64_gcc_install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Configuring GCC&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Before I could &lt;code&gt;make&lt;/code&gt; the GCC installation in this new directory I needed to configure GCC using the &lt;code&gt;configure&lt;/code&gt; script in the git repo which would also configure GCC for the current architecture.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd x86_64_gcc_install 
$ $PWD/../gcc/configure --prefix=$HOME/spo600/x86_64_gcc_install/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I set the configure file from within the install directory and also included the prefix argument to tell the configure script where I want GCC to be installed&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Building GCC&lt;/strong&gt;: &lt;/p&gt;

&lt;p&gt;The makefile was used with the &lt;code&gt;-j 4&lt;/code&gt; argument, which set the amount of CPU cores during the installation to 4.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ make -j 4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The make process for GCC on x86_64 architecture took almost 2 hours with four parallel jobs.&lt;/p&gt;

&lt;p&gt;After this, the makefile and configuration options were added to the install directory. To finish the installation and create the working program I installed the binaries to the &lt;code&gt;x86_64_gcc_install/bin&lt;/code&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ make install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Building GCC for AArch64
&lt;/h2&gt;

&lt;p&gt;I began building GCC on the other environment with AArch64 architecture instead of x86_64&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initial setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The process for obtaining the source code and creating the install directory was the same&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;$ &lt;/span&gt;git clone https://gcc.gnu.org/git/gcc.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, this step took a couple of minutes as there were a lot of individual files to download&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;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;aarch64_gcc_install
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;aarch64_gcc_install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Configuring GCC&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Once again, configuring GCC using the &lt;code&gt;configure&lt;/code&gt; script in the git repo which would also configure GCC for the current architecture with the prefix argument for configure location.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd x86_64_gcc_install 
$ $PWD/../gcc/configure --prefix=$HOME/spo600/x86_64_gcc_install/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this, the makefile and configuration options were added to the install directory&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Building GCC&lt;/strong&gt;: &lt;/p&gt;

&lt;p&gt;I then used 5 CPU cores with the &lt;code&gt;-j 5&lt;/code&gt; option to see if there was any difference in speed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ make -j 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this, it took just under 2 hours and was marginally faster as I had added more multiple cores.&lt;/p&gt;

&lt;p&gt;I then as with x86, installed binaries to &lt;code&gt;aarch64_gcc_install/bin&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;$ make install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Confirming installation
&lt;/h2&gt;

&lt;p&gt;For each installation, the runnable programs were available in the &lt;code&gt;install_dir/bin&lt;/code&gt; directory and to show that GCC was installed for the specific architecture I ran the architecture-specific program (usually including the x86/AArch64 name). For example here was the x86_64 bin folder:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D2JOvtph--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jbe2zfz9ly1sml3cw4m7.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D2JOvtph--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jbe2zfz9ly1sml3cw4m7.JPG" alt="Image of x86 bin folder" width="800" height="111"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To confirm that the newly built GCC compilers were fully functional, I created a Hello World C program in each environment which had the following structure:&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="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&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;"Hello x86_64!&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="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&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;&lt;em&gt;The x86_64 part is replaced with AArch64 in its version&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Compiling and Running x86_64
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TXjC-9KO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xpbad362dxwz9uu1xcyl.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TXjC-9KO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xpbad362dxwz9uu1xcyl.JPG" alt="Compiling and running x86 gcc" width="800" height="97"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To run a program using the installed GCC I used the relative path to the bin folder in my install directory. Usually when fresh installing GCC you would set the bin folder as a &lt;code&gt;$PATH&lt;/code&gt; variable but in this case there was already a version of GCC in the environment.&lt;/p&gt;

&lt;p&gt;To 100% confirm that it is built on x86_64 I used the file command on the object file:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RTIv9AEW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qflq4tukokz5coo6pg3t.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RTIv9AEW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qflq4tukokz5coo6pg3t.JPG" alt="Running file command to see the x86 file name" width="800" height="56"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Compiling and Running AArch64
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YBucjyHX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rbiiirhi524a6vtgol9x.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YBucjyHX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rbiiirhi524a6vtgol9x.JPG" alt="running and compiling AArch64 gcc" width="800" height="75"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Same as above I used the relative path name with the specific AArch64 compiler. &lt;/p&gt;

&lt;p&gt;Confirming with the file command:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4nhz0_Bs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jns7itak7egxtk1mxbur.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4nhz0_Bs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jns7itak7egxtk1mxbur.JPG" alt="Running the file command on AArch64" width="800" height="68"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This experience serves as a testament to the power of open-source development and the versatility of GCC as a cross-compiler tool.&lt;/p&gt;

</description>
      <category>spo600</category>
      <category>opensource</category>
      <category>beginners</category>
      <category>portability</category>
    </item>
    <item>
      <title>Code Refactoring and Git Rebase</title>
      <dc:creator>Ian Jacobs</dc:creator>
      <pubDate>Sat, 14 Oct 2023 01:10:28 +0000</pubDate>
      <link>https://dev.to/ijacobscpa/code-refactoring-and-git-rebase-20a7</link>
      <guid>https://dev.to/ijacobscpa/code-refactoring-and-git-rebase-20a7</guid>
      <description>&lt;p&gt;This week in my open source program I spent time refactoring my code in my &lt;a href="https://dev.to/ijacobscpa/textml-2gic"&gt;textml&lt;/a&gt; program located on my GitHub here &lt;a href="https://github.com/ijacobs-cpa/textml"&gt;https://github.com/ijacobs-cpa/textml&lt;/a&gt;. In addition, I also experimented with git rebase to edit commits made on a refactoring branch. &lt;/p&gt;

&lt;h2&gt;
  
  
  Refactoring Process
&lt;/h2&gt;

&lt;p&gt;Before beginning to refactor my code for this week I had to find where best to focus on refactoring as I had already refactored some code on my own time. &lt;/p&gt;

&lt;p&gt;I mainly focused on refactoring my main file &lt;code&gt;textml.py&lt;/code&gt; and improving my modules as the main function had barely been updated since the first version of the program and could be reduced. The file with the main function was also updated recently with a lot of command-line processing which could be concentrated elsewhere. I also focused here as I had refactored the convertUtils module on my own time, so I wanted to focus elsewhere.&lt;/p&gt;

&lt;p&gt;To refactor this section of code I first wanted to separate code that dealt with processing the command line into its own module. I had already removed the converting functions into their own module so to organize this I decided to store all future modules in their own &lt;code&gt;bin/&lt;/code&gt; directory except for the main &lt;code&gt;textml.py&lt;/code&gt; program which would remain at the root of the project. &lt;/p&gt;

&lt;p&gt;With this, I moved any argparse usage and TOML file processing into its own module and then referenced the module from the main to get the command line arguments. This effectively split the file into two.&lt;/p&gt;

&lt;p&gt;Next, I began looking at how I stored these command line args as variables in my main program and I decided to move them to a class object effectively extracting a class from the code. This helps when these variables need to be passed to a function as I can just pass the entire class allowing for easier maintainability and expansion in the future:&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="nn"&gt;bin.cli&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;ARGS&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ConvertProperties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="c1"&gt;# Properties for converted file 
&lt;/span&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;outDir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;userInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;userInput&lt;/span&gt;
        &lt;span class="n"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;outDir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;outDir&lt;/span&gt;
        &lt;span class="n"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lang&lt;/span&gt;

&lt;span class="n"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ConvertProperties&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="c1"&gt;# Instanced class of properties
&lt;/span&gt;    &lt;span class="n"&gt;ARGS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;ARGS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;ARGS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lang&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this implemented I then went to work on extracting a function out of the code in my main where it would run the convert functions. This was repeated for directories or files and could be simplified into a single function effectively extracting a function from reused code. &lt;/p&gt;

&lt;p&gt;This was completed by providing the class object of converting properties with a file name into a function like below:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fileProps&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;      &lt;span class="c1"&gt;# Function to process file in proper file type
&lt;/span&gt;    &lt;span class="n"&gt;ext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;splitext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&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;ext&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;".txt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;                                       &lt;span class="c1"&gt;# Checking if each file's type is supported before converting
&lt;/span&gt;        &lt;span class="n"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convertText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;outDir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# Text Conversion
&lt;/span&gt;    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;ext&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;".md"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;                               
        &lt;span class="n"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convertMD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fileProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;outDir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fileProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Markdown conversion
&lt;/span&gt;    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;                                                     &lt;span class="c1"&gt;# Prints error if file is not supported
&lt;/span&gt;        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error!: Invalid file type for: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" (Expected .txt, .md)"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, I updated some variable names in my program to make them more descriptive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Git rebase
&lt;/h2&gt;

&lt;p&gt;For this refactoring, I created a separate refactoring branch and committed each step separately. I wanted to group these commits into one single commit with descriptions of all the changes. &lt;/p&gt;

&lt;p&gt;This was done using git rebase allowing me to squash all commits into one picked one like the demonstration below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git rebase main -i
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a text editor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pick 4710009 Commit message 1
squash 0c01069 Commit message 2
squash fd8e932 Commit message 3
squash f9d85bf Commit message 4
squash bfac3d3 Commit message 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This then converted all my individual commits into one commit with all commit info. I then amended the commit message to indicate that this singular commit was all refactoring. &lt;/p&gt;

&lt;p&gt;Its information and all code changes mentioned can be viewed &lt;a href="https://github.com/ijacobs-cpa/textml/commit/0f7d34bb2bf004e84493280e1b3a1269c4c81fb7"&gt;Here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>git</category>
      <category>opensource</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Code Contributions Using Git Remotes</title>
      <dc:creator>Ian Jacobs</dc:creator>
      <pubDate>Sat, 07 Oct 2023 02:58:14 +0000</pubDate>
      <link>https://dev.to/ijacobscpa/code-contributions-using-git-remotes-3fi8</link>
      <guid>https://dev.to/ijacobscpa/code-contributions-using-git-remotes-3fi8</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;For my Open-Source class this week I collaborated with a classmate to add a new feature to their text-to-HTML converter adding support for &lt;a href="https://toml.io/en/"&gt;TOML&lt;/a&gt; configuration files.&lt;/p&gt;

&lt;p&gt;Before beginning contributing with this addition I familiarized myself with their project's code and structure while beginning to think about how I was going to implement it. &lt;/p&gt;

&lt;h2&gt;
  
  
  Contributing
&lt;/h2&gt;

&lt;p&gt;To start, I created an &lt;a href="https://github.com/Amnish04/til-page-builder/issues/10"&gt;Issue&lt;/a&gt; in my classmate's project detailing what I was going to add and how I would add it. &lt;/p&gt;

&lt;p&gt;To add support for &lt;a href="https://toml.io/en/"&gt;TOML&lt;/a&gt; files I first needed to find a proper &lt;code&gt;.toml&lt;/code&gt; file parser that would be compatible with my classmate's project in Python. I ended up using the &lt;a href="https://github.com/hukkin/tomli"&gt;tomli&lt;/a&gt; on recommendation from the project owner for parsing program options from a &lt;code&gt;.toml&lt;/code&gt; file. The tomli library was added to version 3.11 of Python.&lt;/p&gt;

&lt;p&gt;After being approved to work on the project I began to implement the &lt;a href="https://github.com/hukkin/tomli"&gt;tomli&lt;/a&gt; TOML file parser in my classmates' repo. Their project was separated into many different modules which made adding any changes easier as I wouldn't have to update as many functions as they all referenced one module. &lt;/p&gt;

&lt;p&gt;The module in question dealt with command line arguments passed to the program and used Python's argparse library to export an object of required program options that are used around the program. In this module is where I would do most of the work by adding a &lt;code&gt;-c&lt;/code&gt;, and &lt;code&gt;--config&lt;/code&gt; argument option using argparse that accepted &lt;code&gt;.toml&lt;/code&gt; files, then adding a check to see if a config file was passed where if there was it would process and overwrite any program options with ones in the file.&lt;/p&gt;

&lt;p&gt;I then sent the changes as a &lt;a href="https://github.com/Amnish04/til-page-builder/pull/12"&gt;pull request&lt;/a&gt; and after updating the readme and some other things requested by the maintainer my addition was merged into the main project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reviewing a Pull Request with Git Remote
&lt;/h2&gt;

&lt;p&gt;In my own text-to-HTML project, I also received a &lt;a href="https://github.com/ijacobs-cpa/textml/pull/13"&gt;pull request&lt;/a&gt; adding support for TOML config files. &lt;/p&gt;

&lt;p&gt;Once the pull request was made I then needed to review the change and test it. To do this I set a remote to the forked branch of my repo and then fetched the contents into my repo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git remote add &amp;lt;name-of-student&amp;gt; &amp;lt;https://git-url-of-other-studnet-fork.git&amp;gt;
$ git fetch &amp;lt;name-of-student&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I then created a new branch with the remote additions added to my main repo so that I could test the new additions as if they were merged:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git checkout -b &amp;lt;branch-name&amp;gt; &amp;lt;name-of-student&amp;gt;/&amp;lt;branch-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allowed me to easily make updates or pull any new changes the contributor makes. &lt;/p&gt;

&lt;p&gt;After reviewing the pull request I saw it was good to go I used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git merge &amp;lt;student-name&amp;gt;/issue-10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which automatically merged the pull request into my repo from my created remote mentioned above.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;After completing these activities, I've learned a lot about remotes and how they can be set up to directly work with pull requests which is very useful for reviewing. I also was able to view another person's code and test my ability to add and try to emulate how the code was used which improved my overall skill.&lt;/p&gt;

&lt;p&gt;The difficulty that I encountered when working on these was that I made the mistake of adding the remote branch of my repos forked pull request branch to the repo of another project. Thinking that I screwed up I ended up learning how to remove remotes by using &lt;code&gt;git push origin -d&lt;/code&gt; to delete the remote branch from the incorrect repo.&lt;/p&gt;

</description>
      <category>github</category>
      <category>beginners</category>
      <category>opensource</category>
      <category>osd600</category>
    </item>
    <item>
      <title>An Example of Merging Parallel Branches in GitHub</title>
      <dc:creator>Ian Jacobs</dc:creator>
      <pubDate>Fri, 29 Sep 2023 18:51:04 +0000</pubDate>
      <link>https://dev.to/ijacobscpa/an-example-of-merging-parallel-branches-in-github-1ii4</link>
      <guid>https://dev.to/ijacobscpa/an-example-of-merging-parallel-branches-in-github-1ii4</guid>
      <description>&lt;p&gt;This week in my open-source course I am practicing creating and merging branches in my &lt;a href="https://dev.to/ijacobscpa/textml-2gic"&gt;textml&lt;/a&gt; text-to-HTML converter located on my GitHub at &lt;a href="https://github.com/ijacobs-cpa/textml"&gt;https://github.com/ijacobs-cpa/textml&lt;/a&gt;. The program takes a &lt;code&gt;.txt&lt;/code&gt; or &lt;code&gt;.md&lt;/code&gt; file and converts it to a usable HTML file with proper tags. &lt;/p&gt;

&lt;p&gt;To practice creating and merging branches for my program. I decided to add 2 new features to my program:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Adding support for an optional &lt;code&gt;-l&lt;/code&gt;, &lt;code&gt;--lang&lt;/code&gt; language argument that specifies the  attribute in the root &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; element in the final converted HTML file.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;For example, &lt;code&gt;./textml.py french.txt --lang fr&lt;/code&gt; would set &lt;code&gt;&amp;lt;html lang="fr"&amp;gt;&lt;/code&gt; the language to french in the root &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; element.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Adding the conversion of &lt;code&gt;---&lt;/code&gt; in markdown files to the &lt;code&gt;&amp;lt;hr&amp;gt;&lt;/code&gt; horizontal rule element in HTML.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For each of these new features, I created an issue on my projects repository:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/ijacobs-cpa/textml/issues/10"&gt;Language Support Issue&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/ijacobs-cpa/textml/issues/11"&gt;Horizontal rule Issue&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once this was done I created a new branch for each issue on my local repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git checkout -b issue-10
$ git checkout -b issue-11
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I then started to implement the first new feature into my code on its respective branch making sure not to add any changes to the main branch. &lt;/p&gt;

&lt;p&gt;After this was done I moved to the other branch to implement the second new feature:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ git checkout issue-11&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;During this process, I found moments when I was testing the feature that I was working on and tried to run the program with the other already implemented feature from the other branch as an optional argument only to see it not work. This shows that if you are working on multiple unmerged branches make sure you understand the base limitations of your code. &lt;/p&gt;

&lt;h2&gt;
  
  
  Merging the Branches
&lt;/h2&gt;

&lt;p&gt;After completing and testing the current issue branch's new feature I was ready to merge the parallel branches into the main branch and I started with the second one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git checkout main
...
$ git merge issue-11
Updating 5f96795..23098af
Fast-forward
 convertUtils.py          |  4 +++-
 examples/mdTest/test3.md | 11 +++++++++++
 2 files changed, 14 insertions(+), 1 deletion(-)
 create mode 100644 examples/mdTest/test3.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As can be seen above git uses a "Fast-forward" strategy merge as the unchanged main branch has no changes so no conflicts come up as the branches are merged.&lt;/p&gt;

&lt;p&gt;I then went and merged the issue-10 branch with the main branch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git merge issue-10
Auto-merging convertUtils.py
Merge made by the 'recursive' strategy.
 README.md       |  6 +++++-
 convertUtils.py | 12 ++++++------
 textml.py       | 13 +++++++++----
 3 files changed, 20 insertions(+), 11 deletions(-)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time when merging it used the recursive strategy as we are trying to merge the issue-10 branch into the main branch which has been merged already with the issue-11 branch essentially making this a 3-way recursive merge.&lt;/p&gt;

&lt;p&gt;Thankfully, there were no merge conflicts and the issue branches were merged into the main branch successfully. I then pushed the changes to GitHub to finish up.&lt;/p&gt;

&lt;p&gt;Here are links to the merge commits on GitHub:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/ijacobs-cpa/textml/commit/c1e4bff3aa7c9be4f370bd1ef5c2ea5991bb8a86"&gt;Issue 10 Merge (recursive)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/ijacobs-cpa/textml/commit/ed50a9dd372576254b56967892bac1511af24c7b"&gt;Issue 11 Merge (fast-forward)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Working on branches seems like a very good way to go about adding changes to a project on GitHub as it provides a good way to modify and test your code without removing the original and makes a project compatible with the open-source community when wanting to work with others simultaneously. &lt;/p&gt;

</description>
      <category>github</category>
      <category>opensource</category>
      <category>beginners</category>
      <category>osdc</category>
    </item>
    <item>
      <title>6502 Programming</title>
      <dc:creator>Ian Jacobs</dc:creator>
      <pubDate>Thu, 28 Sep 2023 04:37:41 +0000</pubDate>
      <link>https://dev.to/ijacobscpa/6502-programming-3b44</link>
      <guid>https://dev.to/ijacobscpa/6502-programming-3b44</guid>
      <description>&lt;p&gt;For my portability and optimization class, I am taking a look at the 6502 assembly code in preparation for modern assembly code. I am using a 6502 emulator located &lt;a href="http://6502.cdot.systems/" rel="noopener noreferrer"&gt;here&lt;/a&gt; that includes a bitmap display and a text output so we can visually see the output for the assembly code including a memory monitor to see the added memory.&lt;/p&gt;

&lt;p&gt;I will be running some 6502 assembly code to see the results while calculating the time it takes to run and performing some extra experiments in this blog.&lt;/p&gt;

&lt;p&gt;The instructions for creating programs with this CPU are very minimal and a manual used for this lab and in the course can be found &lt;a href="https://www.pagetable.com/c64ref/6502/?tab=2#" rel="noopener noreferrer"&gt;here&lt;/a&gt; with all instructions for the 6502 processer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Calculating Performance
&lt;/h2&gt;

&lt;p&gt;The following code fills the bitmap with a solid colour:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lda #$00    ; set a pointer in memory location $40 to point to $0200
    sta $40     ; ... low byte ($00) goes in address $40
    lda #$02    
    sta $41     ; ... high byte ($02) goes into address $41

    lda #$07    ; colour number

    ldy #$00    ; set index to 0

loop:   sta ($40),y ; set pixel colour at the address (pointer)+Y

    iny     ; increment index
    bne loop    ; continue until done the page (256 pixels)

    inc $41     ; increment the page
    ldx $41     ; get the current page number
    cpx #$06    ; compare with 6
    bne loop    ; continue until done all pages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Timing Results
&lt;/h3&gt;

&lt;p&gt;Below are the timing results from each instruction used above including how many cycles it would take to complete which is then transformed into time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjv90jl1lhgsvcb3w4dj2.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjv90jl1lhgsvcb3w4dj2.JPG" alt="Timing result of the above code"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A bit of clarification, the bitmap display is 32x32 pixels long and takes that amount of space in bits in the 6502's memory, and because we are looping and changing each pixel. The cycle count for those operations is 32x32 = 1024 split into 4 pages of 256 pixels.&lt;/p&gt;

&lt;p&gt;This overall means that the program requires 10326 cycles to complete which assuming a 1 MHz CPU speed would take 0.01036 seconds to complete.&lt;/p&gt;

&lt;h3&gt;
  
  
  Memory
&lt;/h3&gt;

&lt;p&gt;During the execution of the code, memory is used for each instruction used and for variables. The total memory used for this program was the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8trvn9p921gddbhcb27g.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8trvn9p921gddbhcb27g.JPG" alt="Memory used"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just to note: The answer of 8KB is not the max used during the program but it is the total amount of bytes used during the entire program. The byte values for the instructions were found in the manual &lt;a href="https://www.pagetable.com/c64ref/6502/?tab=2#" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Optimized code
&lt;/h3&gt;

&lt;p&gt;To optimize this code for better time I removed the loading of the x register to the beginning of the program instead of in the page loop. I then compare x to the current high-bit (since it's incremented) which would tell me if it is within the page's boundary for the bitmap.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    lda #$00     ; a pointer in memory location $40 to point to $0200
    sta $40     ; low byte ($00) goes in address $40
    lda #$02    
    sta $41     ; high byte ($02) goes into address $41

    LDX #$06    ; Loading number of pages

    LDA #$06    ; Yellow color code
    LDY #$00    ; set Y register index to 0

loop:   
      STA ($40),y   ; Set pixel colour at the address (pointer)+Y
    INY        ; Increment Y register
    BNE loop    ; Continue until done the page (256 pixels)

    INC $41      ; increment the page
    CPX $41      ; Comparing the high bit to the number of pages
    BNE loop     ; continue until done all pages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here are the new timings below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flecgn87u0wdua4ubylez.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flecgn87u0wdua4ubylez.JPG" alt="Timing results for above, optimized version"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As can be seen, my new "optimized" implementation doesn't really shave off that much time only 0.000006 seconds.&lt;/p&gt;

&lt;p&gt;I am not sure exactly how to cut more time from this program. I knew that it most likely had something to do with how the loops were constantly repeating instructions and that it could be optimized there somehow. &lt;/p&gt;

&lt;h2&gt;
  
  
  Modifying the Code
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Colouring Each Page
&lt;/h3&gt;

&lt;p&gt;Here is code that will add 1 to the accumulator used for getting the colour code for each pixel after every page so that its colour updates each page change.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  lda #$00  ; set a pointer in memory location $40 to point to $0200
    sta $40     ; low byte ($00) goes in address $40
    lda #$02    
    sta $41     ; high byte ($02) goes into address $41

    LDX #$06    ; Loading number of pages

    LDA #$06    ; Yellow colour code
    LDY #$00    ; set Y register index to 0

loop:   
        STA ($40),y     ; Set pixel colour at the address (pointer)+Y
    INY     ; Increment Y register
    BNE loop    ; Continue until done the page (256 pixels)

    ADC #$01    ; Adds 1 to the accumulator to update the color
                 ; for each page
    INC $41      ; increment the page
    CPX $41      ; Comparing the high bit to the number of pages in x
    BNE loop     ; continue until done all pages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz2zg7b1ijkb8mso88xil.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz2zg7b1ijkb8mso88xil.JPG" alt="Multi color page output in stacks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Experiments
&lt;/h2&gt;

&lt;h3&gt;
  
  
  TYA
&lt;/h3&gt;

&lt;p&gt;Adding the TYA instruction at the beginning of the loop:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxhehwu30b4z41ivja14y.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxhehwu30b4z41ivja14y.JPG" alt="Results of using TYA in bitmap display; vertical lines of different colour"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After adding TYA it causes the bit map to display vertical lines of different colours. It appears that it is displaying each available colour in a loop for each pixel as each horizontal bit on the display is a different colour on each line and there are both 16 different colours and 32 bits on the display so it shows each colour twice.&lt;/p&gt;

&lt;h3&gt;
  
  
  LSR
&lt;/h3&gt;

&lt;p&gt;Including LSR after and with the TYA instruction:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjvpq0s67wyoerzc8av4b.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjvpq0s67wyoerzc8av4b.JPG" alt="Results of TYA and LSR. Thicker lines"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When adding LSR after TYA it causes each different coloured vertical line to become thicker meaning that there is only 1 set of the 16 different colours showing. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbwrjq7uznn470r3d4917.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbwrjq7uznn470r3d4917.JPG" alt="Results of Using 2 LSR statements. wider lines plus overlapping"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adding more LSR instructions continually causes the lines to become thicker as after 3 LSR instructions there are 8 lines but since there are 16 colours available they overlap each other on every other line.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjo9h15je3x75do8z5otm.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjo9h15je3x75do8z5otm.JPG" alt="5 lsr result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This eventually causes the single-width lines to be displayed horizontally once 5 instructions of LSR are performed. Additionally, it only repeats the first 8 colors instead of the 16.&lt;/p&gt;

&lt;h3&gt;
  
  
  ASL
&lt;/h3&gt;

&lt;p&gt;Restarting the process by adding TYA I added ASL instead which caused the following.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi8zbqr6rou0y69et0y1m.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi8zbqr6rou0y69et0y1m.JPG" alt="ASL Result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The display once again displayed vertical lines for different colours, however, this time compared to using LSR some of the colours were skipped altogether. When referring to the &lt;a href="https://wiki.cdot.senecacollege.ca/wiki/6502_Emulator" rel="noopener noreferrer"&gt;6502 emulator colour code chart on this page&lt;/a&gt; it seems that the ASL operation ignores one colour every time it loops meaning that only 8 out of the 16 colours are repeated for the 32 bits.&lt;/p&gt;

&lt;p&gt;When adding more ASL operations like before, it seems that the program skips more and more for each ASL opcode added with each ASL added effectively halving the number of colours available (starting from 16) as seen below. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawpy1xeu5nl8kgvo3jd8.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawpy1xeu5nl8kgvo3jd8.JPG" alt="2 ASL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This culminates in 4 ASL instructions as it only shows the first colour: black, because 4 ASL instructions == 2^4 = 16 | 16/16 =1 meaning that the first colour is repeated for each pixel. &lt;/p&gt;

&lt;p&gt;When referencing the manual located &lt;a href="https://www.pagetable.com/c64ref/6502/?tab=2" rel="noopener noreferrer"&gt;here&lt;/a&gt; ASL is an "Arithmetic shift left" which means that ASL performs a bitshift to the left which ends up dividing the byte by 2 explaining what is happening here with each additional instruction.&lt;/p&gt;

&lt;h2&gt;
  
  
  INY
&lt;/h2&gt;

&lt;p&gt;Another experiment to perform is to add more INY (increment y register) instructions for each loop. I would expect this to increment the counter in 5's meaning it makes skip colouring pixels.&lt;/p&gt;

&lt;p&gt;However, what happens is the screen still fills with colour but when running at the lowest speed you can see the pixels being filled in with 5 spaces apart for each pixel repeating 256 times which means that it overflows like (255 -&amp;gt; 300 (overflow) x --&amp;gt; 004) and so on meaning that eventually, the pixels fill up each page as usual then the entire display.&lt;/p&gt;

&lt;h2&gt;
  
  
  Random Colours
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lda #$00    ; set a pointer in memory location $40 to point to $0200
    sta $40     ; ... low byte ($00) goes in address $40
    lda #$02    
    sta $41     ; ... high byte ($02) goes into address $41

    lda $FE         ; Sets random colour (number) to accumulator
    ldx #$06    ; get the current page number
    ldy #$00    ; set index to 0

loop:   LDA $FE       ; Adds random colour for next pixel
    STA ($40), y
    iny
    BNE loop

    inc $41     ; increment the page
    cpx $41       ; compare with 6
    bne loop    ; continue until done all pages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code loads the hexadecimal number 0xFE (254) which is defined as a pseudo-random number in the peripherals of the 6502 processor. This generates a random number assigned to the accumulator before each pixel is stored, allowing each pixel to be a random colour. Here are two examples with the above code on the &lt;a href="http://6502.cdot.systems/" rel="noopener noreferrer"&gt;6502 Emulator&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa0cx64dp3ppha2k55amd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa0cx64dp3ppha2k55amd.jpg" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges
&lt;/h2&gt;

&lt;p&gt;The code below sets the bit display to a single colour except for the middle 4 pixels.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    lda #$00    ; set a pointer in memory location $40 to point to $0200
    sta $40     ; ... low byte ($00) goes in address $40
    lda #$02    
    sta $41     ; ... high byte ($02) goes into address $41

    lda $FE        ; Sets random colour (number) to accumulator
    ldx #$06    ; get the current page number
    ldy #$00    ; set index to 0

loop:   

    STA ($40), y
    iny
    BNE loop

    inc $41     ; increment the page
    cpx $41         ; compare current page to x (0600)
    bne loop    ; continue until done all pages

    ADC #$01    ; Add one to the colour code

    STA $03EF   ; Storing the new coloured pixels at middle location
    STA $03F0
    STA $040F
    STA $0410

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My solution to this challenge was to manually add each of the middle pixel locations and assign them +1 to the colour chosen (kept the random colour choice in this code so it is still random).&lt;/p&gt;

&lt;p&gt;Here is the output:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgpry3n1wsf319mmfx8ie.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgpry3n1wsf319mmfx8ie.JPG" alt="Challenge output: full screen except for middle two pizels"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;After completing this lab, and doing the experiments and challenges. I believe that I have learned the basic instructions and addressing methods for this assembler including the little-endian design philosophy when it comes to byte storage. &lt;/p&gt;

&lt;p&gt;When first viewing the assembler demos and lab I was sort of intimidated by the randomness of how the code operated but throughout this lab, I experimented and got a good beginner's understanding of how the 6502 processer operates and how assembly operates in general.&lt;/p&gt;

</description>
      <category>spo600</category>
      <category>assembly</category>
      <category>6502</category>
      <category>beginners</category>
    </item>
    <item>
      <title>First Code Contributions</title>
      <dc:creator>Ian Jacobs</dc:creator>
      <pubDate>Fri, 22 Sep 2023 03:50:18 +0000</pubDate>
      <link>https://dev.to/ijacobscpa/first-code-contributions-2m0j</link>
      <guid>https://dev.to/ijacobscpa/first-code-contributions-2m0j</guid>
      <description>&lt;p&gt;This week in my open source development course I practiced creating and managing pull requests to another person's project and my for my project &lt;a href="https://dev.to/ijacobscpa/textml-2gic"&gt;textml&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;For my part, I was working on the Waypoint project located here at &lt;a href="https://github.com/rabroldan/Waypoint"&gt;https://github.com/rabroldan/Waypoint&lt;/a&gt; which is a text-to-HTML converter that allows for custom CSS styling and allows live creation and editing of files submitted to the program. &lt;/p&gt;

&lt;h2&gt;
  
  
  Adding a Feature
&lt;/h2&gt;

&lt;p&gt;My task was to add support for converting markdown/&lt;code&gt;.md&lt;/code&gt; files to HTML and this started with creating a &lt;a href="https://github.com/rabroldan/Waypoint/issues/8"&gt;Issue&lt;/a&gt;. After receiving approval I then forked the repo and created an issue branch to add my changes located here: &lt;a href="https://github.com/ijacobs-cpa/Waypoint/tree/issue-8"&gt;Forked Issue branch&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;I then began making the changes. My main goal was to not overly change the design of the code that was already there so I made sure that any changes were similar to how the project owner's code was made. I ended up creating a new function that would process any &lt;code&gt;.md&lt;/code&gt; files that were passed to the program or created by the program. &lt;/p&gt;

&lt;p&gt;After creating the function I had to find examples of when the program was checking the file type and have it also check for a markdown file which made me edit multiple points around their code so that it would correctly convert &lt;code&gt;.md&lt;/code&gt; and &lt;code&gt;.txt&lt;/code&gt; files to HTML in there respective locations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making a Pull Request
&lt;/h2&gt;

&lt;p&gt;Once this was done I tested the program under different scenarios (folder, single file, creating a new file, and a new folder) with markdown files and made sure that it would properly be converted and then pushed all the changes to my branch and submitted a pull request which can be seen &lt;a href="https://github.com/rabroldan/Waypoint/pull/9"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;As can be seen, it was reviewed by the owner and merged into the project after we had a small chat about some of the features on Slack.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling a pull request
&lt;/h2&gt;

&lt;p&gt;My project on my GitHub &lt;a href="https://github.com/ijacobs-cpa/textml"&gt;here&lt;/a&gt; which is a text to HTML converted also received a pull request to add markdown file/folder support. &lt;/p&gt;

&lt;p&gt;Just like my previous process they:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Forked the repo&lt;/li&gt;
&lt;li&gt;Created an issue branch&lt;/li&gt;
&lt;li&gt;Added changes to the branch&lt;/li&gt;
&lt;li&gt;Submitted the branch as a pull request&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Pull requests can be found &lt;a href="https://github.com/ijacobs-cpa/textml/pull/9"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After receiving the pull request I went to work on testing if it would work and found that it had a lot of problems: &lt;/p&gt;

&lt;p&gt;It had some oversights that caused the program to crash, it wasn't saving files to the correct location, and it would only convert a single &lt;code&gt;.md&lt;/code&gt; file and had no directory support.&lt;/p&gt;

&lt;p&gt;I opened a &lt;a href="https://github.com/ijacobs-cpa/textml/pull/9#issuecomment-1728674060"&gt;thread&lt;/a&gt; on the pull request explained some of the issues that were present with their implementation and then asked them to fix them before I could merge.&lt;/p&gt;

&lt;p&gt;Later, they updated their commit branch with changes that fixed their previous issues. After a couple more fixes that I required from them, I merged the new code into my repo.&lt;/p&gt;

&lt;p&gt;Overall I liked the whole process I just would have preferred if the contributor stuck to how my code was formatted and operated but their additions were solid and they kept most of the continuity of my program intact. &lt;/p&gt;

&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;Overall this process was interesting. At first, I had a couple of problems understanding how best to implement the code for the project I was working on as I found the program to be written very uniquely and different from what I was used to. &lt;/p&gt;

&lt;p&gt;After running and testing the different outcomes I understood where I needed to add something. I also wanted to make sure that I didn't interfere with the original design of the code too much&lt;/p&gt;

&lt;p&gt;Being new to Python I learned a good amount from reading the code. I saw a very good use of the &lt;a href="https://docs.python.org/3/library/argparse.html"&gt;argparse&lt;/a&gt; Python library which has a much more efficient way of handling command line arguments and I plan to implement it into a future version of my program. &lt;/p&gt;

&lt;p&gt;I also learned a good amount about creating and managing pull requests including linking issues that automatically close when pull requests are complete.&lt;/p&gt;

&lt;p&gt;If I were to do something differently next time I would ask for more info on how the maintainer would like me to modify their program so I could know how much I could drift away from their design.&lt;/p&gt;

</description>
      <category>github</category>
      <category>opensource</category>
      <category>osdc</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Textml</title>
      <dc:creator>Ian Jacobs</dc:creator>
      <pubDate>Mon, 18 Sep 2023 19:54:18 +0000</pubDate>
      <link>https://dev.to/ijacobscpa/textml-2gic</link>
      <guid>https://dev.to/ijacobscpa/textml-2gic</guid>
      <description>&lt;p&gt;I have created my first version of a truly open-source program called Textml. It is a Python program that converts text files to basic HTML files. &lt;/p&gt;

&lt;p&gt;To use the program you provide either a text file or a folder containing text files to be converted to HTML. They will then be saved to a default directory &lt;em&gt;textml/&lt;/em&gt; for use. &lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Provide custom output directory 

&lt;ul&gt;
&lt;li&gt;Creates new directory if output directory doesn't exist&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Title parsing from text files (First line followed by 2 newlines only)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The project is located on my GitHub at &lt;a href="https://github.com/ijacobs-cpa/textml"&gt;https://github.com/ijacobs-cpa/textml&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Instructions
&lt;/h2&gt;

&lt;p&gt;To run this program you first need to clone the repository from GitHub and open the repository locally.&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;$ &lt;/span&gt;git clone https://github.com/ijacobs-cpa/textml.git
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;textml/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To run make sure that you have Python installed on your system:&lt;br&gt;
&lt;code&gt;$ python --version&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once installed you can then run the Python script:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ python textml.py [file/directory] &amp;lt;commands&amp;gt; [command argument]&lt;/code&gt;&lt;br&gt;
or&lt;br&gt;
&lt;code&gt;$ python textml.py &amp;lt;options&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Options
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;-v, --version&lt;/td&gt;
&lt;td&gt;Displays version of the program&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-h, --help&lt;/td&gt;
&lt;td&gt;Displays a help message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-o, --output &lt;/td&gt;
&lt;td&gt;Specifies the location to save converted files, creates a new folder if location doesn't exist, defaults to textml/&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Examples
&lt;/h2&gt;

&lt;p&gt;Converting a file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ python textml.py myfile.txt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Converting all files in a directory:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ python textml.py mydirectory/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Running Commands:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ python textml.py -v&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Specifying Output Directory:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ python textml.py myFile.txt -o newDir/&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;Here is an example of a text file being converted:&lt;/p&gt;

&lt;p&gt;command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ python textml.py examples/liveTest/index.txt -o examples/liveTest/&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;Today I learned


Documenting some information I've learned today

Here is some information:


6502 Assembly Notes (KEY_terms):

#{number} adds a nuber
${hex} adds a hexadecimal

LDA = Load the accumulator

LDY = Load the Y register
LDX = Load the X register

STA = Store the accumulator
STY = Store the Y register
STX = Store the X register

CPX = compare THE x register
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!doctype html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Today I learned&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Today I learned&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Documenting some information I've learned today&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Here is some information:&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;6502 Assembly Notes (KEY_terms):&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;#{number} adds a nuber&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;${hex} adds a hexadecimal&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;LDA = Load the accumulator&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;LDY = Load the Y register&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;LDX = Load the X register&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;STA = Store the accumulator&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;STY = Store the Y register&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;STX = Store the X register&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;CPX = compare THE x register&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Static site: &lt;a href="https://ijacobs-cpa.github.io/textml/examples/liveTest/index.html"&gt;https://ijacobs-cpa.github.io/textml/examples/liveTest/index.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>osdc</category>
      <category>github</category>
      <category>html</category>
    </item>
    <item>
      <title>Investigating Open Source Software Packages</title>
      <dc:creator>Ian Jacobs</dc:creator>
      <pubDate>Sun, 17 Sep 2023 20:28:18 +0000</pubDate>
      <link>https://dev.to/ijacobscpa/investigating-open-source-software-packages-2c8l</link>
      <guid>https://dev.to/ijacobscpa/investigating-open-source-software-packages-2c8l</guid>
      <description>&lt;p&gt;This is my first blog post for my Optimization and Portability class at Seneca College. I am researching some open-source software packages and explaining how they handle code changes in the open-source environment. &lt;/p&gt;

&lt;p&gt;For this investigation, I've found 2 software packages with different licenses:&lt;/p&gt;

&lt;p&gt;First, I'll be taking a look at &lt;a href="https://opencv.org/"&gt;OpenCV&lt;/a&gt; which uses a &lt;a href="https://www.apache.org/licenses/LICENSE-2.0"&gt;Apache&lt;/a&gt; license. They're an open-source computer vision software package that uses machine learning and its goal is the commercialization of machine perception for use in the mainstream including things like identifying faces and objects, tracking objects, and extracting 3D models of objects (Learn more at &lt;a href="https://opencv.org/about/"&gt;https://opencv.org/about/&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Their primary mode of accepting code changes is through their GitHub repository &lt;a href="https://github.com/opencv"&gt;here&lt;/a&gt; where users can contribute to the project by submitting issues and making pull requests. An example I'll be looking at is this &lt;a href="https://github.com/opencv/opencv/pull/24266"&gt;Pull Request&lt;/a&gt; for an update to the code. &lt;/p&gt;

&lt;p&gt;The process is pretty typical for a GitHub project the contributor  Creates a branch, Clones the branch repository locally, Creates the change/patch, and then Submits the patch as a pull/merge request to the main repo on GitHub.&lt;/p&gt;

&lt;p&gt;The review process then begins and a maintainer is assigned to the issue who tags the request and adds it as a part of a future patch milestone. In this case, the maintainer asks another maintainer to review the code and small discussions begin about the methods the contributor uses where other contributors discuss some of the changes. The original contributor then makes some changes and then the patch is approved and merged into the main project. 4 people are involved in getting this patch accepted into the main project&lt;/p&gt;

&lt;p&gt;Another project that I'll be looking at is the VLC media player and the VideoLAN software located at &lt;a href="https://www.videolan.org/"&gt;https://www.videolan.org/&lt;/a&gt; which is a popular multimedia video player that uses a &lt;a href="https://www.gnu.org/licenses/gpl-3.0.html"&gt;GPLv3 (GNU Public License)&lt;/a&gt;. They have their own organization GitLab located &lt;a href="https://code.videolan.org/explore/projects/starred"&gt;here&lt;/a&gt; for contributions to their code and require people to have an account with their organization before they are allowed to make any changes. &lt;/p&gt;

&lt;p&gt;I'll be describing another accepted patch through a merge request located at this &lt;a href="https://code.videolan.org/videolan/vlc/-/merge_requests/4252"&gt;Merge Request&lt;/a&gt;. Like GitHub, the contributor creates a branch including their addition for their merge request. &lt;/p&gt;

&lt;p&gt;In this request, the contributor creates the patch and submits it for review. The maintainer then provides tags for the request and addresses some of the methods used for changing. A small discussion between the maintainer and the contributor happens which then gets some others involved (including the president of VideoLAN Jean-Baptiste Kempf) on the methods used which results the the original contributor updating their merge branch. After this, the branch is approved by the maintainer and given a tag saying it can be added to a future update, and a couple of days later it is grouped together with many other merge requests which all together are finally pushed to the main branch.&lt;/p&gt;

&lt;p&gt;With this, you can see how the head maintainers organize the patches provided by merge requests by grouping approved ones and adding them all at once. This patch involved 5 people from the review stage to the approving and merging stage.&lt;/p&gt;

&lt;p&gt;By looking at these different open-source methods for software packages we see how many people contributing and reviewing the project help maintain it as both a relevant project and a free and open-source one.&lt;/p&gt;

</description>
      <category>spo600</category>
      <category>opensource</category>
      <category>programming</category>
      <category>git</category>
    </item>
    <item>
      <title>Reviewing and Being Reviewed: First Reviews in Open-Source</title>
      <dc:creator>Ian Jacobs</dc:creator>
      <pubDate>Sat, 16 Sep 2023 00:56:57 +0000</pubDate>
      <link>https://dev.to/ijacobscpa/reviewing-and-being-reviewed-first-reviews-in-open-source-j65</link>
      <guid>https://dev.to/ijacobscpa/reviewing-and-being-reviewed-first-reviews-in-open-source-j65</guid>
      <description>&lt;p&gt;In my Open-Source course this week we worked on completing a small project to convert text files to HTML files. While it wasn't due for a couple of days after this task; before then we needed to review another student's release and get ours reviewed. &lt;/p&gt;

&lt;p&gt;To get someone to review my project I made use of Slack where I listed my GitHub repo asking for someone to provide feedback for it by creating issues in GitHub. I responded to another request of someone to have their project reviewed which allowed me to find someone who did not have any feedback already and was willing to examine my project.&lt;/p&gt;

&lt;p&gt;When testing and reviewing my partner's code I found we both used the same programming language, Python which I am very unfamiliar with. Initially, when looking at the code I saw that they were more proficient and used a lot of different methods that I was unaware of. Through testing, I found that their code was solid and worked fine under a lot of different circumstances, and was learning from just looking at their code. For example, I was unaware you could run a Python script using the &lt;code&gt;./{python program}&lt;/code&gt; method if you gave the file execute privileges as I kept using the &lt;code&gt;python &amp;lt;program name&amp;gt; method&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;Getting my project reviewed I thought my partner who looked more proficient in Python would be more critical of my implementation. However, they focused more on the project details and future flexibility of the code which I would find helpful. Instead of going into detail on things that I might have overlooked when it came to efficiency. &lt;/p&gt;

&lt;p&gt;The main issue that I found in my partner's project was that they were missing many README details including installation instructions making it slightly unclear to someone trying to install it. The other issue/improvement I found was when a text file was converted to HTML it didn't add any `&lt;br&gt; tags for when there was a double newline. This meant that if there were any extra spacings between paragraphs they wouldn't be in the HTML document. This however was something that was optional and something that each project creator could choose to include or not but mentioned as an improvement.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Issues with my partner's project:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/mingming-ma/txt2html/issues/1"&gt;Issue 1&lt;/a&gt; | In this issue I discussed how my partner's README could be improved as theirs was lacking some of the required details and details that could help one understand how to use the program.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mingming-ma/txt2html/issues/2"&gt;Issue 2&lt;/a&gt; | In this issue I discussed how their version and help flags could use some improvements including more details on how to run the program in the --help tag.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mingming-ma/txt2html/issues/3"&gt;Issue 3&lt;/a&gt; | This issue dealt with the fact that any optional features that are present in the project are not documented or explained and suggested a feature that could be added for future optional requirements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mingming-ma/txt2html/issues/4"&gt;Issue 4&lt;/a&gt; | This issue dealt with how their program dealt with spaces in HTML and how they could have included some &lt;code&gt;&amp;lt;br /&amp;gt;&lt;/code&gt; tags to more accurately reflect the text document they were processing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mingming-ma/txt2html/issues/5"&gt;Issue 5&lt;/a&gt; | This issue dealt with code formatting issues and for them to add a couple more comments in the program.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Issues for my project:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/ijacobs-cpa/textml/issues/1"&gt;Issue 1&lt;/a&gt; &amp;amp; &lt;a href="https://github.com/ijacobs-cpa/textml/issues/4"&gt;Issue 4&lt;/a&gt; | These issues dealt with reformatting of the README document to make it more user friendly and optimized. This involved moving some sections closer to the top and making sure to use constant styling.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ijacobs-cpa/textml/issues/2"&gt;Issue 2&lt;/a&gt; | This issue dealt with displaying the differences between different versions and creating a changelog to document them in the readme.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ijacobs-cpa/textml/issues/3"&gt;Issue 3&lt;/a&gt; | This issue was about an error in my help message that showed an incorrect use of the program when used.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ijacobs-cpa/textml/issues/5"&gt;Issue 5&lt;/a&gt; | This was an issue that one of my initial functions was not dynamic enough that it could be expanded upon in the future so they suggested I make it able to fulfill future users requirements. &lt;/p&gt;

&lt;p&gt;These issues made by my partner helped me document my project more efficiently and helped with making sure my program passed all the specifications required for submission while also providing improvements to the code for flexibility in the future.&lt;/p&gt;

&lt;p&gt;To sum it up, I gained a lot of experience opening and closing issues in GitHub and testing another person's program, and found that you can learn a lot from reviewing other people's code. I feel like it is good to have someone with a fresh perspective view code that is not theirs as they can catch things that others can't.&lt;/p&gt;

</description>
      <category>github</category>
      <category>opensource</category>
      <category>osdc</category>
      <category>programming</category>
    </item>
    <item>
      <title>Open-Source Introduction</title>
      <dc:creator>Ian Jacobs</dc:creator>
      <pubDate>Fri, 08 Sep 2023 18:02:23 +0000</pubDate>
      <link>https://dev.to/ijacobscpa/open-source-introduction-2phl</link>
      <guid>https://dev.to/ijacobscpa/open-source-introduction-2phl</guid>
      <description>&lt;p&gt;Hey, my name is Ian and I am a programming student at Seneca College in the 6th semester of the CPA program and am going to get my start in the world of open-source development through this course. &lt;/p&gt;

&lt;p&gt;I took this course because I want a good introduction to the open-source development community as I've only worked on more closed projects for assignments and personal learning. It also will teach me to interact more with open source communities and work on related projects which will help me with a future career in software development.&lt;/p&gt;

&lt;p&gt;My goals in this term are to learn the proper methods and etiquette for contributing to open-source projects while also testing the many programming languages and skills that I have acquired during my time in college with real-world projects.&lt;/p&gt;

&lt;p&gt;I'm not sure what types of projects I would like to contribute to exactly and would like to research and experiment with many different types of projects. I do however have a focus on tools that help with back-end development and useful tools that perform a task simply and efficiently. This leads to the project that I've chosen to research for this post.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Genymobile/scrcpy"&gt;scrcpy&lt;/a&gt; is a program written mainly in C that allows you to view and control your mobile device on your computer. I first came across this project a year ago when trying to find a program to emulate my mobile device for a school assignment. When I first downloaded it was extremely easy to set up and start and worked seamlessly, and besides allowing you to view your mobile's screen it also allowed you to control your phone with your mouse and keyboard which I found great as many other screen capturing methods don't have this level of emulation. &lt;/p&gt;

&lt;p&gt;The project is located at &lt;a href="https://github.com/Genymobile/scrcpy"&gt;https://github.com/Genymobile/scrcpy&lt;/a&gt; and was created by &lt;a href="https://www.genymotion.com/aboutus/"&gt;Genymoblie&lt;/a&gt; which is a company specializing in Android emulation that has other similar projects that allow for the use of Android devices on other platforms include in the cloud. &lt;/p&gt;

&lt;p&gt;I find companies like these that specialize in efficient software to be very interesting and insightful for an open-source project as one of the reasons it works so well may have come from help from the open-source community and it inspires me to participate in projects like these in the open-source community. &lt;/p&gt;

</description>
      <category>opensource</category>
      <category>beginners</category>
      <category>osd600</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
