Friday, 5 March 2021

Python: how to use enum in python

Description:

  • Enums have been added to Python 3.4 as described in PEP 435. It has also been backported to 3.3, 3.2, 3.1, 2.7, 2.6, 2.5, and 2.4 on pypi.
  • For more advanced Enum techniques try the aenum library (2.7, 3.3+, same author as enum34. Code is not perfectly compatible between py2 and py3, e.g. you'll need __order__ in python 2).  
  • To use enum34, do $ pip install enum34
  • To use aenum, do $ pip install aenum

Program:

  # Python enum usage
# Check : http://velrajcoding.blogspot.in
#

# Below is supported from python 3.4 onwards.
from enum import Enum

class Animal(Enum):
    DOG = 1
    CAT = 2
    LION = 3


class EnumAssign():
    def __init__(self):
        self.Animal_enum = Animal

    def display_ani(self, value):
        print("The EnumAssign Animal.DOG  : ")
        print(self.Animal_enum.DOG)

        print("The EnumAssign Animal.DOG value : %d" % self.Animal_enum.DOG.value)

        print("The EnumAssign Animal.DOG  name : %s" % self.Animal_enum.DOG.name)
        if self.Animal_enum.DOG.value == value:
            print("The requested value is DOG")
        elif (self.Animal_enum.CAT.value == value):
            print("The requested value is CAT")
        elif (self.Animal_enum.LION.value == value):
            print("The requested value is LION")
def main():
    print()
    print("****************** Starting Main fun ******************************")
    print()
    obj = EnumAssign();
    obj.display_ani(Animal.CAT.value)

#print("The value of enum is    : %d " % Animal.DOG)
print("The display Outside function Direct access Animal.DOG : ")
print(Animal.DOG)

print("The display Outside function Direct access Animal.DOG value : %d" % Animal.DOG.value)

print("The display Outside function Direct access Animal.DOG  name : %s" % Animal.DOG.name)


if __name__ == "__main__":
    main()

   

Output

h]$ python3 py_enum.py
The display Outside function Direct access Animal.DOG :
Animal.DOG
The display Outside function Direct access Animal.DOG value : 1
The display Outside function Direct access Animal.DOG  name : DOG

****************** Starting Main fun ******************************

The EnumAssign Animal.DOG  :
Animal.DOG
The EnumAssign Animal.DOG value : 1
The EnumAssign Animal.DOG  name : DOG
The requested value is CAT


Reference:
     https://stackoverflow.com/questions/36932/how-can-i-represent-an-enum-in-python


Friday, 28 August 2020

Shared Libraries with GCC on linux

 

  •  Create an .so file and run that file, link the .so from the same path to the executable.

Program:

Program file 1 Header file  (foo.h):

/* Shared Libraries with GCC on linux
 * Check : http://velrajcoding.blogspot.in
 */
#ifndef foo_h__
#define foo_h__

extern void foo(void);

#endif  // foo_h__

Program file 2 foo.c:
 
/* Shared Libraries with GCC on linux
 * Check : http://velrajcoding.blogspot.in
 */

#include <stdio.h>


void foo(void)
{
        printf("Hello, I am a shared library");
}

Program file 3 Main file (main.h):
/* Shared Libraries with GCC on linux
 * Check : http://velrajcoding.blogspot.in
 */
#include <stdio.h>
#include "foo.h"

int main(void)
{
    puts("This is a shared library test...");
    foo();
    return 0;
}

Compile & execute:

Step 1: Compiling with Position Independent Code

[so_crete]$ ls
foo.c foo.h main.c
[so_crete]$
[so_crete]$ gcc -c -Wall -Werror -fpic foo.c
[so_crete]$ ls
foo.c foo.h foo.o main.c
[so_crete]$

Step 2: Creating a shared library from an object file

[so_crete]$ gcc -shared -o libfoo.so foo.o
[so_crete]$ ls
foo.c foo.h foo.o libfoo.so main.c
[so_crete]$

Step 3: Linking with a shared library

[so_crete]$ gcc -Wall -o test main.c -lfoo
/bin/ld: cannot find -lfoo
collect2: error: ld returned 1 exit status
[so_crete]$

Tell GCC where to find the shared library
[so_crete]$ pwd
/users/vkutrala/vel/sample/so_crete
[so_crete]$ gcc -L /users/vkutrala/vel/sample/so_crete -Wall -o test main.c -lfoo
[so_crete]$ ls
foo.c foo.h foo.o libfoo.so main.c test
[so_crete]$

Step 4: Making the library available at runtime

[so_crete]$ ./test
./test: error while loading shared libraries: libfoo.so: cannot open shared object file: No such file or directory
[so_crete]$

Using LD_LIBRARY_PATH

[so_crete]$ echo $LD_LIBRARY_PATH

[so_crete]$ LD_LIBRARY_PATH=/users/vkutrala/vel/sample/so_crete:$LD_LIBRARY_PATH
[so_crete]$ ./test
./test: error while loading shared libraries: libfoo.so: cannot open shared object file: No such file or directory
[so_crete]$
[so_crete]$
[so_crete]$
What happened? Our directory is in LD_LIBRARY_PATH, but we did not export it. In Linux, if you do not export the changes to an environment variable, they will not be inherited by the child processes
[so_crete]$ export LD_LIBRARY_PATH=/users/vkutrala/vel/sample/so_crete:$LD_LIBRARY_PATH
[so_crete]$ ./test
This is a shared library test...
Hello, I am a shared library
[so_crete]$

Reference:
     https://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html

 

Read About Dynamic loading lib(run time load or patch update)

Friday, 31 July 2020

python: how to use pexpect without installing

We can use the pexpect without installing, below is the best way to use:

  1. Downloaded Pexpect 2.4 ( https://pypi.org/project/pexpect/2.4/#files).
    • We tested on python 2.7.10 version, need to check in latest python version, not sure this will work on latest.
    • Also seems not support in latest pexpect version because latest version doesn't have pexpect.py file iteself. so best use pexpect 2.4 version. 
       2. Place pexpect.py next to my script
       3. import pexpect in my script.


It will work.

Monday, 29 July 2019

strtok vs strtok_r - extract tokens from strings

Name

strtok, strtok_r - extract tokens from strings

Synopsis

       #include <string.h>

       char *strtok(char *str, const char *delim);
       char *strtok_r(char *str, const char *delim, char **saveptr);

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
       strtok_r(): _POSIX_C_SOURCE
           || /* Glibc versions <= 2.19: */ _BSD_SOURCE || _SVID_SOURCE

Note:

1. Don't use original string pointer because, it will replace the
   delimiters with '\0'.
2. Suppose Original string is constant then crash will be hit.
3. strtok will use the global pointer, so could not use in thread & 
   2 strtok simultaneously.
4. strtok_r is a thread save, because it use the local pointer for
   next iteration.

Description:

  • strtok() and strtok_r() for splitting a string by some delimiter.
  • The strtok() function breaks a string into a sequence of zero or more nonempty tokens.
  • On the first call to strtok(), the string to be parsed should be specified in str.
  • In  each subsequent call that should parse the same string, str must be NULL.
  •  
  • The  delim argument specifies a set of bytes that delimit the tokens in the parsed string.
  • The strtok_r() function is a reentrant  version  strtok().
  • The  saveptr  argument  is a pointer  to  a  char * variable that is used internally by strtok_r() in order to maintain context between successive calls that parse the same string.

 Return:

  • Return a pointer to the next token, or NULL if there are no more tokens.

Program:

/* strtok vs strtok_r by Velraj.K
   Check : http://velrajcoding.blogspot.in
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
    char *str1, *str2, *token, *subtoken;
    char *saveptr1, *saveptr2;
    char str_second[256] = {'\0'};
   // *str_second = "VelrajKutralam Indian";
    int j;

    if (argc != 4) {
        fprintf(stderr, "Usage: %s  <1st delim="">  <2nd subdelim="">\n",
                argv[0]);
        exit(EXIT_FAILURE);
    }

    /* The original string will be replaced with null in delimiter places */
    strncpy(str_second, argv[1], sizeof(str_second));

    printf("\n\n\t\t Do the token using strtok_r \n");

    /* use strtok_r */
    for (j = 1, str1 = argv[1]; ; j++, str1 = NULL) {
        token = strtok_r(str1, argv[2], &saveptr1);
        if (token == NULL)
            break;
        printf("%d: %s\n", j, token);

        for (str2 = token; ; str2 = NULL) {
            subtoken = strtok_r(str2, argv[3], &saveptr2);
            if (subtoken == NULL)
                break;
            printf(" --> %s\n", subtoken);
        }
    }
   printf("Original value = %s \n", argv[1]);

    printf("\n\n\t\tDo the token using strtok str_second = %s \n", str_second);
    /* Initialize the variable to NULL to start token again with strtok */
    str1 = NULL;
    str2 = NULL;
    token = NULL;
    subtoken = NULL;
    saveptr1 = NULL;
    saveptr2 = NULL;

    /* use strtok */
    for (j = 1, str1 = str_second; ; j++, str1 = NULL) {
        token = strtok(str1, argv[2]);
        if (token == NULL)
            break;
        printf("%d: %s\n", j, token);

       /*
        *  Could not use the 2nd strtok with different delim because it uses the global pointer
        *  to process the next token.
        */
#if 0
        for (str2 = token; ; str2 = NULL) {
            subtoken = strtok(str2, argv[3]);
            if (subtoken == NULL)
                break;
            printf(" --> %s\n", subtoken);
        }
#endif
    }

    exit(EXIT_SUCCESS);
}

 

Output:

:~/velrajk/sample/learn$ ./a.out  velrajkutralamindia l v


                 Do the token using strtok_r
1: ve
 --> e
2: rajkutra
 --> rajkutra
3: amindia
 --> amindia
Original value = ve


                Do the token using strtok str_second = velrajkutralamindia
1: ve
2: rajkutra
3: amindia

Tuesday, 23 July 2019

Dynamic loading lib(run time load or patch update)

dlopen:

void * dlopen(const char *filename, int flag);
Flag:
  RTLD_LAZY --> ``resolve undefined symbols as code from the dynamic library is
                  executed''
  RTLD_NOW  --> ``resolve all undefined symbols before dlopen() returns and 
                  fail if this cannot be done''
                  opening the library take slightly longer (but it speeds up 
                  lookups later);  
  RTLD_GLOBAL --> Optional -> external symbols defined in the library will be made
                  available to subsequently loaded libraries

  • If the libraries depend on each other (e.g., X depends on Y), then you need to load the dependees first (in this example, load Y first, and then X).

Return:

  • ``handle'' that should be considered an opaque value to be used by the other DL library routines.
  • Return NULL On error.

dlerror:

  • which returns a string describing the error from the last call to dlopen(), dlsym(), or dlclose().
  • Return null if there is no error.
  • Call dlerror() first (to clear any error condition that may have existed), then call dlsym() to request a symbol, then call dlerror() again to see if an error occurred.

dlsym:

void * dlsym(void *handle, char *symbol);
      handle -> value returned from dlopen
      symbol -> NIL-terminated string.

Note:

For Run time patch(Dynamic loading the .so file):
   We must close the old handler & re open the library again,if there is
   any change in library. Otherwise changes won't be loaded.
   Hence for Run time patch, we must close & open the library again.

Return:

  • Return a NULL result if the symbol wasn't found.   

dlclose:

  • Closes a DL library.
  •  The dl library maintains link counts for dynamic file handles, so a dynamic library is not actually deallocated until dlclose has been called on it as many times as dlopen has succeeded on it.
  •  It's not a problem for the same program to load the same library multiple times.

Return:

  • Returns 0 on success, and non-zero on error

Program:

Program 1: create shared library:

 

/* Dynamic loading lib(run time load or patch update)
 * Check : http://velrajcoding.blogspot.in
 */

#include <stdio.h>

void run_load()
{
    printf("Velraj Run time loading 1st \n");


    return;
}
 

Program 2: Dynamic loader program:

 
/* Dynamic loading lib(run time load or patch update)
 * Check : http://velrajcoding.blogspot.in
 */

#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>

#define LIB_USR_DEF   "~/velrajk/sample/learn/librunlib.so"

enum {
    DL_LOAD_LIB = 1,
    DL_CALL_FUN,
    DL_EXIT,
};

void hline(char ch)
{
    int i = 0;

    for ( ; i < 80; printf("%c", ch), i++);
    printf("\n");

    return;
}
int main(int argc, char **argv)
{
    void *handle = NULL;
    void (*fun_symbol)();
    char *ret = NULL;
    int  ch = 0;

    while (1) {
        printf("\n\n");
        hline('*');
        printf("Find the DL library options:  \n\t 1. Load the library\n\t 2.Call the function\n\t 3.Exit\n Enter your choice:   ");
        scanf("%d", &ch);

        switch (ch) {
            case DL_LOAD_LIB:
                /*
                 * For Run time path:
                 *       We must close the old handler & re open the library again, if there is any change in library.
                 *       Otherwise changes won't be loaded.
                 *       Hence for Run time patch, we must close & open the library again.
                 */
                if (handle) {
                    dlclose(handle);
                }
                handle = dlopen(LIB_USR_DEF, RTLD_LAZY);
                if (!handle) {
                    fputs (dlerror(), stderr);
                    continue;
                }
                printf("Successfully opened an library \n");
                break;
            case DL_CALL_FUN:
                /* clear error code */
                dlerror();
                fun_symbol = dlsym(handle, "run_load");
                if ((ret = dlerror()) != NULL)  {
                    /* handle error, the symbol wasn't found */
                    printf("dlerror return error msg as:%s \n", ret);
                    continue;
                }

                /* symbol found, calling the symbol */
                (*fun_symbol)();
                break;
            case DL_EXIT:
                exit(1);
                break;
            default:
                printf("Choose the correct choice \n");
                break;
        }
    }

    dlclose(handle);

    return 0;
}
 

Output:

Program 1: Create Library

   :~/velrajk/sample/learn$ gcc -fPIC -shared -o librunlib.so dl_run_lib.c

Program 2: Dynamic loading

   :~/velrajk/sample/learn$ gcc dlopen.c -ldl


:~/velrajk/sample/learn$ ./a.out


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:   1
Successfully opened an library


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:   2
Velraj Run time loading 1st


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:



<!-- Here itself changed the library content as 2nd but without dlclose & dlopen, new value won't effect -->

2
Velraj Run time loading 1st


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:   2
Velraj Run time loading 1st


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:   2
Velraj Run time loading 1st


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:   1
Successfully opened an library


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:   2
Velraj Run time loading 2nd


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:   3

Reference:
    http://tldp.org/HOWTO/Program-Library-HOWTO/dl-libraries.html
    https://developer.ibm.com/tutorials/l-dynamic-libraries/
 

Shared library program:   Shared Libraries with GCC on linux


Monday, 22 July 2019

File based Database using Gunzip


  • zlib is a software library used for data compression.
  • The zlib library provides Deflate compression and decompression code for use by zip, gzip, png (which uses the zlib wrapper on deflate data).
  • gzread decompresses as you read it.

Program:

 
/* File based Database using Gunzip
 * Check : http://velrajcoding.blogspot.in
 */

#include <stdio.h>
#include <zlib.h>    // For gunzip

enum {
    TAG_VER = 1,
    TAG_DATA,
};

#define FILE_PATH_TMP     "file_gz_db.gz.tmp"
#define FILE_PATH         "file_gz_db.gz"
#define VERSION_1         1
#define STU_ID            100
#define STU_NAME          "Velraj"
#define STU_TOTAL         500

void save_db()
{
    char buf[256] = {0};
    int  len = 0;
    gzFile gz_file = NULL;

    if (!(gz_file = gzopen(FILE_PATH_TMP, "wb"))) {
        printf("Failed gzopen !");
        return;
    }

    len = snprintf(buf, sizeof(buf), "%d\a%d\n", TAG_VER, VERSION_1);
    if (len != gzwrite(gz_file, buf, len)) {
        printf("Failed to writing db header!");
        goto end;
    }

    len = snprintf(buf, sizeof(buf), "%d\a%d\a%s\a%d\n", TAG_DATA,
                   STU_ID, STU_NAME, STU_TOTAL);
    if (len != gzwrite(gz_file, buf, len)) {
        printf("Failed to writing db header!");
        goto end;
    }
    rename(FILE_PATH_TMP, FILE_PATH);

end:
    gzclose(gz_file);
    return;
}

void read_db()
{
    gzFile gz_file = NULL;
    char   buf[256] = {0}, str_tag[16] = {0}, str_stu_id[12] = {0}, str_name[64] = {0}, str_total[12] = {0};
    int    tag = 0, version = 0, ret = 0;

    if (!(gz_file = gzopen(FILE_PATH, "rb"))) {
        printf("gzopen is failed to open the file");
        return;
    }
    if (gzgets(gz_file, buf, sizeof(buf)) == NULL) {
        printf("File is doesn't have any content");
        goto end;
    }

    sscanf(buf, "%d\a%d", &tag, &version);
    if ((tag != TAG_VER) || (version != VERSION_1)) {
        printf("Failed tag or version");
        goto end;
    }

    while (gzgets(gz_file, buf, sizeof(buf))) {
        ret = sscanf(buf, "%d", &tag);
        if (tag != TAG_DATA) {
            continue;
        }

        ret = sscanf(buf, "%*[^\a]\a%[^\a]\a%[^\a]\a%[^\n]", str_stu_id, str_name, str_total);
        if (ret != 3) {
            printf("Failed to read student details ret:%d", ret);
            continue;
        }
        printf("Read the data : ID:%s, Name:%s, Total:%s \n", str_stu_id, str_name, str_total);
    }

end:
    gzclose(gz_file);
    return;
}

int main()
{
    save_db();
    read_db();

    return 0;
}
 

Output:

:~/velrajk/sample$ gcc file_list_of_data.c  -lz
:~/velrajk/sample$ ls -l file_gz_db.gz
ls: cannot access file_gz_db.gz: No such file or directory
:~/velrajk/sample$ ./a.out
Read the data : ID:100, Name:Velraj, Total:500
:~/velrajk/sample$ ls -l file_gz_db.gz
-rw-rw-r-- 1 labuser labuser 41 Jul 22 14:44 file_gz_db.gz
:~/velrajk/sample$ gunzip file_gz_db.gz
:~/velrajk/sample$ cat file_gz_db
11
2100Velraj500
:~/velrajk/sample$





Reference:
https://www.lemoda.net/c/gzfile-read/
https://stackoverflow.com/questions/39233004/zlib-gzopen-returns-a-compressed-file-stream-does-it-decompress-the-file
https://github.com/madler/zlib

Friday, 19 July 2019

Write binary(struct) data to the file using fread, fwrite

NAME

       fread, fwrite - binary stream input/output

SYNOPSIS

#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);


Note:

 3rd Argument is sizeof nmemb:
      nmemb -> number of size to be written into fiile.
              Eg: if 1 then only one node will be written into file.
                  if 2 then two nodes will be written into the file.

DESCRIPTION

  • The function fread() reads nmemb elements of data, each size bytes long, from the stream pointed to by stream, storing them at the location given by ptr.
  • The function fwrite() writes nmemb elements of data, each size bytes long, to the stream pointed to by stream, obtaining them from the location given by ptr.

RETURN VALUE

  • On  success, fread() and fwrite() return the number of items read or written.  This number equals the number of bytes transferred only when size is 1.
  • If an error occurs, or the end of the file is reached, the return value is a short item count (or zero).
  • fread() does not distinguish between end-of-file and error, and callers must use feof(3) and ferror(3) to determine which occurred.
  • Note: To verify error need to use ferror() API, could not use return value.

Program:

 

/* Write binary(struct) data to the file using fread, fwrite
 * Check : http://velrajcoding.blogspot.in
 */

#include <stdio.h>
#include <errno.h>
#include <string.h>

#define FILE_NAME       "binary_fil"
#define FILE_NAME_2     "binary_fil2"
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif

typedef struct node {
    int   value1;
    int   value2;
    char  name[64];
} node_t;

void display_node(node_t *node, char *msg)
{
    if (!node || !msg) {
        printf("Node or msg is null \n");
        return;
    }
    printf("Node %s Value 1:%d Value2:%d name:%s \n", msg, node->value1, node->value2, node->name);

    return;
}

int file_write_struct(node_t *node, const char *file, size_t num_node)
{
    FILE        *fp = NULL;

    if (!(fp = fopen(file, "w"))) {
        printf("Error in open an file, error no:%d:<%s> \n", errno, strerror(errno));
        return FALSE;
    }

    /*
     * 3rd Argument is sizeof nmemb:
     *     nmemb -> number of size to be written into fiile.
     *              Eg: if 1 then only one node will be written into file.
     *                  if 2 then two nodes will be written into the file.
     */
    fwrite(node, sizeof(node_t), num_node, fp);
    if (ferror(fp)) {
        printf("Error in write to the file, error no:%d:<%s> \n", errno, strerror(errno));
        return FALSE;
    }
    fclose(fp);

    return TRUE;
}

int file_read_struct(node_t *node)
{
    FILE        *fp = NULL;

    if (!(fp = fopen(FILE_NAME, "r"))) {
        printf("Error in open an file, error no:%d:<%s> \n", errno, strerror(errno));
        return FALSE;
    }

    fread(node, sizeof(node_t), 1, fp);
    if (ferror(fp)) {
        printf("Error in write to the file, error no:%d:<%s> \n", errno, strerror(errno));
        return FALSE;
    }
    fclose(fp);

    return TRUE;
}

int main()
{
    node_t      node[] = { {100, 200, "Velraj Kutralam"},
                           {20, 35, "Kutralam S"} };
    node_t      node_read = {0};

    display_node(node, "before save");
    file_write_struct(node, FILE_NAME, 1);
    file_write_struct(node, FILE_NAME_2, 2);

    file_read_struct(&node_read);
    display_node(node, "after save");

    return 0;
}

 

Output:

:~/velrajk/sample$ ./a.out
Node before save Value 1:100 Value2:200 name:Velraj Kutralam
Node after save Value 1:100 Value2:200 name:Velraj Kutralam
:~/velrajk/sample$ cat binary_fil
d▒Velraj Kutralam:~/velrajk/sample$
:~/velrajk/sample$ cat binary_fil2
d▒Velraj Kutralam#Kutralam S:~/velrajk/sample$


Vim of binary_fil:

d^@^@^@È^@^@^@Velraj Kutralam^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@

Vim of binary_fil2:

^@^@^@È^@^@^@Velraj Kutralam^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^T^@^@^@#^@^@^@Kutralam S^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@