Coding style

25 Nov

Here’s the way I like to lay out my code:

int f (void)
{
  if (x < 100)
  {
    do_something();
  }
  for (i = 0; i < 10; i++)
  {
    body_of_loop();
  }
}

There’s a name for it, but seriously the only point in knowing the name is so you can argue with other coders about it.

Sometimes, when I inherit some code, it helps me understand the code if I reformat it into my style.  I don’t think it is the change in format, so much as the review of the code and touching each section.  But it really helps.

make using preprocessor on macro files

25 Nov

This makefile is what I use to build a set of macro files for TeraTerm.  The macro language supports function calls and the like, but the include file support is very limited, so I use the C preprocessor to handle the include files and use the output file as the macro definition.

# define a variable as a list of files
sources = p0pci.top p0pci_nrn.top p0pci_pbit.top
# define a list of flags
CPPFLAGS := -I../../inc
# Modify a variable changing a common part of each filename
all: $(sources:.top=.ttl)
include $(sources:.top=.d)
# Basic simple rule (new syntax)
%.ttl: %.top
@echo "Building $@"
@gcc -E -P -x assembler-with-cpp $(CPPFLAGS) $*.top > $@

Variable Number of Argument Functions (varargs)

25 Nov

They aren’t type-safe, but many times it is so nice to have a function takes varying numbers of arguments.  The standard C printf function is a perfect example.  And many of the functions I write with var args are logging functions that take a printf-style format string.

Declaring the functions

Fortunately, all you have to do is use the ellipses to represent the variable arguments.  Put them after the last mandatory argument.

/* Log Functions */
void citLogPrintf (UINT32 flag, const char* format, ...);
void citLogPrintfDef (UINT32 flag, const char* format, ...);

Including headers

You need to include stdarg.h to get the macro definitions you will need.

Writing the functions

You will need to declare a variable of type va_list, usually I call it args.

Then call va_start, pass it the variable and the last mandatory argument, e.g. va_start (args, format);

Then you have two options:

  1. Use the va_list to pass to a function which takes a va_list as a parameter, such as vsnprintf.
  2. Process the arguments yourself using the provided macros.

I almost always need option #1, so I don’t have an example of #2.

Sample Code

#include <stdlib.h>
void citLogPrintf (UINT32 flag, const char* format, ...)
{
  va_list     args;
  cit_log     log;
  int         status;
  if (((_citLogRemoteFlags | _citLogLocalFlags) & flag) != 0)
  {
    va_start (args, format);
    vsnprintf (log.message, sizeof(log.message), format, args);
    if ((_citLogLocalFlags & flag) != 0)
    {
      logMsg ("%s", (int) log.message, 2,3,4,5,6);
      millisleep (100);
    }
    if ((_citLogRemoteFlags & flag) != 0)
    {
      /* send a log message to the CIT master */
      log.message_type = CIT_LOG;
      log.lid = _citLid;
      status = msgSend (_citTxPort, &log, sizeof(log), 0, 0);
    }
  }
}

Hello world!

24 Nov
#include <stdio.h>

int main (int argc, char *argv[])
{
    printf ("Hello world!\n");
    return 0;
}
Follow

Get every new post delivered to your Inbox.