how to extend C style IO to user defined types

the other day, we had to extend C style IO to use defined types. Let the code says how we made that work微笑

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

typedef struct tagProcessor
{
  char name[32]; //max length 31
  void (*pf)(va_list* pva); //there must be one and only one expression arg_va(*pva, T) within pf;
  struct tagProcessor* next;
}type_processor;

type_processor** processorList()
{
  static type_processor* theList = 0;
  return &theList;
}

//if multiple registratoins for a type, only the last registraton is meanfull
//we don't provide unregister function for now,
//though a unregister function is not hard to add 
type_processor const* regProcessor(char const* type_name, void (*pf)(va_list*))
{
    type_processor** list;
    type_processor* tp = (type_processor*)malloc(sizeof(type_processor));
    if(tp)
    {
      strncpy(tp->name, type_name, sizeof(tp->name)-1);
      tp->name[sizeof(tp->name)-1] = 0;
      tp->pf = pf;
      list = processorList();
      tp->next = *list;
      *list = tp;
    }
    return tp;
}

type_processor const* findRegEntry(char const* name)
{
  type_processor* tp = *processorList();
  while(tp && 0 != strcmp(tp->name, name))
  {
    tp = tp->next;
  }
  return tp;
}

//types are delimeted by space(s)
void run(char* types, ...)
{
  type_processor const* tp;
  char type[sizeof(tp->name)], *p;
  va_list vl;
  va_start(vl,types);
  if(types)
  {
    while(*types)    
    {
      while(isspace(*types)) ++types; //skip spaces at the begining
      p = type;
      while(!isspace(*types) && *types)
      {
        *p++ = *types++;
      }
      *p = 0;
      if(p == types) //no more data to process
      {
        break;
      }
      tp = findRegEntry(type);
      if(tp)
      {
        if(tp->pf)
        {
           tp->pf(&vl);
        }
        //else
      }
      //else     
    }

  }
  va_end(vl);
}

typedef struct tagABC 
{
  int a;
  double b;
  char c;
}ABC;

void processABC(va_list* pvl)
{
  ABC abc = va_arg(*pvl, ABC);
  printf("%d %lf %c\n", abc.a, abc.b, abc.c);
}

void processABCPointer(va_list* pvl)
{
  ABC* abc = va_arg(*pvl, ABC*);
  printf("%d %lf %c\n", abc->a, abc->b, abc->c);
}

void processInt(va_list* pvl)
{
  printf("%d\n", va_arg(*pvl, int));
}

int main()
{
  regProcessor("ABC", processABC);
  regProcessor("ABC*", processABCPointer);
  regProcessor("int", processInt);
  ABC abc = {56, 78.5, 'L'};
  run("int ABC int ABC*", (int)5, abc, (int)6, &abc);
  return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值