Archive for the ‘Programming’ Category

1
Mar

C Function to Validate ISO 8601 Date Formats Using ‘strptime’

Here’s a demonstration of how to use strptime and a list of format strings to validate, for example, a supplied ISO 8601 date in C or C++. You can play with the code below over at https://ideone.com/4Em3v1. It’s not an extensive list of all ISO 8601 dates, but these are the ones that work within a MySQL query. One improvement that could be made is to handle timezones in datetime strings like ‘2010-01-01T01:01:01-7:00’ and potentially micro seconds (if possible).

This is also a good demonstration for how to easily loop through all elements in an array of undefined size in C.

#define _GNU_SOURCE
#include <stdio.h>
#include <time.h>
#include <string.h>

static int
is_valid_iso8601_date_value(char *in)
{
    struct tm result;
    char **f;
    char *ret;
    char *formats[] = {
        "%Y",
        "%Y-%m",
        "%y-%m",
        "%Y-%m-%d",
        "%y-%m-%d",
        "%Y%m%d",
        "%y%m%d",
        "%Y-%m-%d %T",
        "%y-%m-%d %T",
        "%Y%m%d%H%M%S",
        "%y%m%d%H%M%S",
        "%Y-%m-%dT%T",
        "%y-%m-%dT%T",
        "%Y-%m-%dT%TZ",
        "%y-%m-%dT%TZ",
        "%Y-%m-%d %TZ",
        "%y-%m-%d %TZ",
        "%Y%m%dT%TZ",
        "%y%m%dT%TZ",
        "%Y%m%d %TZ",
        "%y%m%d %TZ",
        NULL
    };

    memset(&result, 0, sizeof(result));

    for (f = formats; f && *f; f++)
    {
        ret = strptime(in, *f, &result);
        if (ret && *ret == '\0')
            return 1;
    }

    return 0;
}

int main(void) {
	
	char date_str[] = "2010-01-01T01:01:01Z";
	
    if (is_valid_iso8601_date_value(date_str))
    {
    	printf("%s is a valid iso8601 date!", date_str);
        return 0;
    }
    else
    {
    	printf("%s is not a valid iso8601 date!", date_str);
		return 1;
    }
}
16
Nov

Getting Started with Python Unit Testing (pyUnit)

The following sections give quick, heavily commented, and ready-to-run examples that will give you a head start in creating a unit test framework in Python (pyUnit). First, we’ll take a look at a standalone module with several simple examples of unit tests. Then, we’ll take a look at a more complicated version that uses modules and test suites.

Here’s the first example. As long as you are running Python version 2.1 or greater, you can copy/paste this code, save it to unittest.py, and run it using python unittest.py.

'''This is a simple program to demonstrate how to create a unittest in
Python. For more information and documentation, please see the official
documentation page here: http://docs.python.org/library/unittest.html'''
 
import unittest #Include the pyUnit unittest framework

def add(a,b,c=0):
   '''A simple adding function to demo unittest'''
   return a+b+c

# The following is the class in which all functions will be ran by unittest
class AddTest(unittest.TestCase):
   ''' Main class for add testing; Can be added to a suite'''

   # The function "setUp" will always be ran in order to setup the
   # test environment before all the tests have run.
   def setUp(self):
      '''Verify environment is setup properly''' # Printed if test fails
      pass

   # The function "tearDown" will always be ran in order to cleanup the
   # test environment after all the tests have run.
   def tearDown(self):
      '''Verify environment is tore down properly''' # Printed if test fails
      pass

   # Functions beginning with "test" will be ran as a unit test.
   def test_positive_add(self):
      '''Verify that adding positive numbers works''' # Printed if test fails
      self.assertEqual(add(10,23,22), 55) # Test will fail if "false" (boolean)
      self.assertEqual(add(11,23), 34)
      self.assertEqual(add(1,1,17), 19)

   # Functions beginning with "test" will be ran as a unit test.
   # @unittest.skip("demonstrating skipping") # Skip this test (Python >= 2.7)
   def test_negative_add(self):
      '''Verify that adding negative numbers works''' # Printed if test fails
      self.assertEqual(add(-12,23), 11)

   # Functions beginning with "test" will be ran as a unit test.
   # In this case, this test will be skipped.
   [email protected]("demonstrating skipping")
   def test_negative_add_skip(self):
      '''Verify that adding negative numbers works''' # Printed if test fails
      self.assertEqual(add(-12,23), 11)

if __name__=='__main__':
   unittest.main()

For more complicated test suites and modularity, please take a look at the git repository I’ve setup on bitbucket.org. Download the source, read the README file, and you’ll be able to have a working example of a testsuite (run with python pyunit_intro/suite/test/unittest_run_all.py).

https://bitbucket.org/dhildreth/pyunit_intro

Source: Much of the code from above was done first in this great introductory presentation given by Chander K. Ganesan at PyCon 2010.

13
Oct

Programmers Tool: Ctag Navigation with vim

If you’re a programmer, you might be interested in taking advantage of the ctags utility to quickly navigate through your source code in a text editor such as VIM.

Ctags is a utility or program that creates an index (aka tag) file of names found in source and header files of various programming languages. This index includes things such as functions, variables, class members, macros, etc. This is great because vim can take advantage of this index and you can more quickly navigate through source files. For more information, wikipedia has a nice article on it here.

To start using ctags, you must first have the ctags utility. A quick check would be to just type ctags --version in the terminal:

[email protected]> ctags --version
ctags (GNU Emacs 23.1)
Copyright (C) 2009 Free Software Foundation, Inc.
This program is distributed under the terms in ETAGS.README

If you have it, then we can immediately start using it. First, build the index by running in the directory where you keep the source code:

ctags source.c

If you’d like to be able to recursively scan all of your source files, you must insure that you’re using the exuberant ctags utility. In a Debian based system, this is simply done with:

sudo apt-get install exuberant-ctags
sudo update-alternatives –config ctags

Then, open the source in vim and use ctrl ] to jump into the tag and ctrl t to jump out of the tag.

There’s quite a bit of information available out there on using these tools together. I would recommend taking a look around. Here are a few that I found:
Stackoverflow: Vim and Ctags tips and tricks
Linux.byexamples: Vim with Ctags

23
Jun

Calculating /proc/cpuinfo BogoMIPS After Kernel Init

Upon starting up your Linux kernel, a bogoMIPS calculation will be made and recorded into /proc/cpuinfo. This is a value that is not dynamically updated, so if you change the clock speed of the CPU, the bogoMIPS value contained in /proc/cpuinfo will not be updated. If all you’re interested in is a simple verification that your CPU speed was changed, you could compile and run the following bogoMIPS calculation program both before and after the clock speed change.

http://www.ibiblio.org/pub/linux/system/status/bogo-1.2.tar.gz

Simply call ‘make’ to compile the program. You may need to modify the Makefile in accordance to your needs (cross compiling, gcc flags, etc). You may notice that the bogoMIPS value calculated by this program is not the same as the value calculated by the kernel. That’s okay. What matters here is that you can verify a change in CPU speed. After all, “bogo” stands for “bogus” which simply means “fake”.

Source:
http://tldp.org/HOWTO/BogoMips/bogo-faq.html

13
May

Yet Another Quick Serial Read c Program

Here’s yet another quick example of a serial capture c program that I came across while at work the other day. I just figured I would share…

int main(int argc, char * argv[]){
while(1){
FILE *fp;

fp = fopen("/proc/bus/usb/001/003", "r");

char buff[100];
while(fscanf(fp, "%s", buff) != EOF){
printf("%sn", buff);
}
fclose(fp);
}
return 0;
}
12
May

Grab Raw Keyboard Input from Event Device Node (/dev/input/event)

The following is a quick c program that will capture raw keyboard data from the event device node such as /dev/input/event1. Simply compile and run with the specific device node as an argument. ie. ./keyboard_key_capture /dev/input/event1.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <dirent.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/time.h>
#include <termios.h>
#include <signal.h>

void handler (int sig)
{
  printf ("nexiting...(%d)n", sig);
  exit (0);
}

void perror_exit (char *error)
{
  perror (error);
  handler (9);
}

int main (int argc, char *argv[])
{
  struct input_event ev[64];
  int fd, rd, value, size = sizeof (struct input_event);
  char name[256] = "Unknown";
  char *device = NULL;

  //Setup check
  if (argv[1] == NULL){
      printf("Please specify (on the command line) the path to the dev event interface devicen");
      exit (0);
    }

  if ((getuid ()) != 0)
    printf ("You are not root! This may not work...n");

  if (argc > 1)
    device = argv[1];

  //Open Device
  if ((fd = open (device, O_RDONLY)) == -1)
    printf ("%s is not a vaild device.n", device);

  //Print Device Name
  ioctl (fd, EVIOCGNAME (sizeof (name)), name);
  printf ("Reading From : %s (%s)n", device, name);

  while (1){
      if ((rd = read (fd, ev, size * 64)) < size)
          perror_exit ("read()");      

      value = ev[0].value;

      if (value != ' ' && ev[1].value == 1 && ev[1].type == 1){ // Only read the key press event
	   printf ("Code[%d]n", (ev[1].code));
      }
  }

  return 0;
} 

Here is an example output from running the above command. Notice that Code[] is printed before the key that was pressed.

# ./keyb_key_cap_x86 /dev/input/by-id/usb-Dell_Dell_USB_Keyboard-event-kbd 
Reading From : /dev/input/by-id/usb-Dell_Dell_USB_Keyboard-event-kbd (Dell Dell USB Keyboard)
Code[30]
aCode[48]
bCode[46]
cCode[32]
dCode[18]
eCode[33]
fCode[34]
gCode[35]
hCode[23]
iCode[36]
jCode[37]
kCode[38]
lCode[50]
mCode[49]
nCode[24]
oCode[25]
pCode[16]
qCode[19]
rCode[31]
sCode[20]
tCode[22]
uCode[47]
vCode[17]
wCode[45]
xCode[21]
yCode[44]
zCode[2]
1Code[3]
2Code[4]
3Code[5]
4Code[6]
5Code[7]
6Code[8]
7Code[9]
8Code[10]
9Code[11]
0

This is only an example program that I picked up from work. I hope it will be of use to somebody out there so it can quickly help you get started with your project.

27
Apr

A Great, Simple, Quick Serial Port Test Program for Linux

For any of you out there who would like to learn about serial programming or are in need of a simple serial program for testing, I would recommend checking out the one from “Captains Universe” here:
http://www.captain.at/howto-simple-serial-port-test-example.php

It’s easy to understand, modify, and compile and I think it’s a valuable tool in any programmers or embedded Linux users arsenal.

22
Apr

Time Tracking and Profiling Your Program with gprof

Until today, I had only heard of the time program to track how much time a program took to execute entirely. This is useful to see if there are any optimizations that can be made to make the program run quicker, but it doesn’t help troubleshoot or debug a program very easily since it only tracks the entry and exit of the program being ran. Another utility that allows you to track time in a more detailed manner is called gprof. Here’s a quote from the CS department of Utah School of Computing (link) explaining it in more detail:

Profiling allows you to learn where your program spent its time and which functions called which other functions while it was executing. This information can show you which pieces of your program are slower than you expected, and might be candidates for rewriting to make your program execute faster. It can also tell you which functions are being called more or less often than you expected. This may help you spot bugs that had otherwise been unnoticed.

Be sure to check out the man pages and other many guides out there that explain how to use it (no need for me to reinvent the wheel).

7
Apr

Convert Small Array to Single Variable and Back Again

Here is a method that will allow you to essentially merge elements of an array into a single variable and then back again in c.

unsigned char mac_addr[6];
long long int x;

x = mac_addr[0] << 40;
x |= mac_addr[1] << 32;
x |= mac_addr[2] << 24;
x |= mac_addr[3] << 16;
x |= mac_addr[4] << 8;
x |= mac_addr[5];

mac_addr[0] = x >> 40;
mac_addr[1] = x >> 32;
mac_addr[2] = x >> 24;
mac_addr[3] = x >> 16;
mac_addr[4] = x >> 8;
mac_addr[5] = x;

You could probably take it a step further and throw it into a loop of sorts. If you have another solution, feel free to share it in the comments below!

26
Mar

Silence the rt73 Driver Message of MimeAssocReqAction()

If you utilize the rt2501usb chipset (rt73 driver) and are connect to your wireless LAN using WPA2 encryption, then you may have noticed a flurry of messages showing up in your syslog or dmesg output, filling up you logs:

[ 1321.830000] MlmeAssocReqAction(): WPA2/WPA2PSK fill the ReqVarIEs with CipherTmp!
[ 1323.980000] MlmeAssocReqAction(): WPA2/WPA2PSK fill the ReqVarIEs with CipherTmp!
[ 1328.170000] MlmeAssocReqAction(): WPA2/WPA2PSK fill the ReqVarIEs with CipherTmp!
[ 1330.480000] MlmeAssocReqAction(): WPA2/WPA2PSK fill the ReqVarIEs with CipherTmp!
[ 1332.990000] MlmeAssocReqAction(): WPA2/WPA2PSK fill the ReqVarIEs with CipherTmp!
[ 1337.060000] MlmeAssocReqAction(): WPA2/WPA2PSK fill the ReqVarIEs with CipherTmp!

It seems to me that these are simply status/debugging messages and don’t serve much of a purpose other than fillings up the logs with information that’s not all that valuable to an end-user. The connection still works, so it doesn’t seem out of line to simply comment out the offending lines in the source code. If you don’t have the source code already, then you’ll need to goto RaLink and download them. There are readme files that will help you compile from scratch. When you have the source code, simply use grep to find the messages:

grep -rn "ReqVarIEs with CipherTmp"

You should find that the lines occur in the assoc.c file at line 348 and line 402. Comment these lines out and recompile. After this, your logs will be scotch-free of all those messages.

Next Page »