Compare Two Firmware Version Strings in C

Table of Contents

  1. Question
  2. Code/Solution
  3. Explantion

1. Question

Develop a C code that compare the two strings, containing the two firmware versions. e.g. char fw_ver1 [] = "1.2.1" and char fw_ver2 [] = '1.2.2". Code has to compare if first version is higher, lower or if equal to the second version. code has the scenarios where version has to ignore the trailing 0 e.g. fw_ver1[] = "1.001" and  fw_ver2 [] = "1.01" both are equal. Create a function that returns the output on the basis of the below 3 conditions possible 

1. Return 1 if version 1 is considered greater than version 2.
2. Return 0 if version 1 is deemed equal to version 2.
3. Return -1 if version 2 is considered greater than version 1.

2. Code

#include <stdio.h>
#include <stdint.h>

uint32_t ret_abs_digit(char *ver, uint32_t *num) {
    uint32_t ret_num = 0;
    uint32_t idx = 0;
    while((ver[idx] != '.') && (ver[idx] != '\0')) {
        ret_num = ret_num * 10;
        ret_num += (ver[idx] - 48);
        idx++;
    }
    *num = ret_num;
    return idx+1;
}

uint32_t compare_versions(char *ver1, char *ver2, uint32_t ver1_len, uint32_t ver2_len) {
    uint32_t idx1 = 0;
    uint32_t idx2 = 0;
    uint32_t num1 = 0;
    uint32_t num2 = 0;
    if(ver1 != NULL  && ver2 != NULL) {
        while((idx1 < ver1_len) || (idx2 < ver2_len)) {
            if(idx1 < ver1_len) {
                idx1 += ret_abs_digit(&ver1[idx1], &num1);
            } else {
               num1 = 0;
            }
            
            if(idx2 < ver2_len) {
                idx2 += ret_abs_digit(&ver2[idx2], &num2);
            } else {
                num2 = 0;
            }

            if(num1 < num2) {
                return -1;
            } else if (num1 > num2) {
                return 1;
            }
        }
    }
    return 0;
}

int main()
{
    char version_1[] = "9.0.0";
    char version_2[] = "9.0.0.1";
    int8_t ret = 0;
    
    ret = compare_versions(version_1, version_2, sizeof(version_1) - 1, sizeof(version_2) - 1);
    
    printf("%d\n", ret);
    if(ret == 0) printf("Both Version Strings Are Same");
    else if(ret == 1) printf("Version1 is > Version2");
    else if(ret == -1) printf("Version2 is > Version1");

    return 0;
}

3. Explantion 

This C program compares two version strings in the format "x.y.z" and returns -1 if the first version is smaller, 1 if the second version is smaller, and 0 if both versions are equal.

Here's a step-by-step explanation:

1. The ret_abs_digit function extracts the numeric part from the version string (before the first dot or null character) and converts it to a uint32_t. It also updates the input pointer num with the extracted value and returns the index of the character after the extracted numeric part.

2. The compare_versions function compares two version strings, ver1 and ver2. It uses ret_abs_digit to extract numeric parts from both versions and compares them. The function returns -1, 1, or 0 based on the comparison result.

3. In the main function:

    1. Two version strings (version_1 and version_2) are defined.
    2. The compare_versions function is called with these version strings and their lengths as arguments.
    3. The result is printed, indicating which version is greater or if they are equal.
    4. Note: The lengths passed to compare_versions are calculated using sizeof and subtracting 1 to exclude the null terminator.

The example versions used are "9.0.1" and "9.0.0.0". The result of the comparison is printed, and in this case, it would print "1" because "9.0.1" is considered greater than "9.0.0.0" based on the versioning scheme.
The code is designed to handle version strings with different numbers of components (e.g., "x.y" and "x.y.z") and compare them numerically component by component.