Simple coroutine library / objects in plain C Snapshot
val.c
Go to the documentation of this file.
00001 #include "val.h"
00002 #include <ctype.h>
00003 
00004 static int parse_spec( const char **pos, VAL_TYPE *type)
00005 {
00006   const char *cur = *pos;
00007   int length = 0;
00008 
00009   if (*cur == '\0') {
00010     return 1;
00011   }
00012 
00013   for( ; isspace(*cur) ; ++cur);
00014 
00015   if (*cur != '%') {
00016     return -1;
00017   }
00018   ++cur;
00019 
00020   if (*cur == 's') {
00021     *type = VAL_TYPE_STRING;
00022     goto ret;
00023   }
00024 
00025   if (*cur == 'p') {
00026     *type = VAL_TYPE_PTR;
00027     goto ret;
00028   }
00029 
00030   for( length = 0; *cur == 'h'; ++cur,++length );
00031    
00032   if ( *cur == 'q') { 
00033      ++cur;
00034      length = 4;
00035   }
00036 
00037   if (*cur != 'd' && *cur != 'u') {
00038     return -1;
00039   }
00040 
00041   switch( length ) {
00042       case 2:
00043         *type = *cur == 'd' ?  VAL_TYPE_INT8 : VAL_TYPE_UINT8;  
00044         goto ret;
00045       case 1:
00046         *type = *cur == 'd' ?  VAL_TYPE_INT16 : VAL_TYPE_UINT16;  
00047         goto ret;
00048       case 0:
00049         *type = *cur == 'd' ?  VAL_TYPE_INT32 : VAL_TYPE_UINT32;  
00050         goto ret;
00051       case 4:
00052         *type = *cur == 'd' ?  VAL_TYPE_INT64 : VAL_TYPE_UINT64;  
00053         goto ret;
00054   }
00055   return -1;
00056 
00057 ret:
00058   *pos = cur + 1;
00059   return 0;
00060 }
00061 
00062 int VALUES_printv( VALUES *values, const char *format, va_list ap )
00063 {
00064   const char *pos;
00065   VAL_TYPE type;
00066   VAL val;
00067   int rt;
00068   ARRAY_reset( &values->values );
00069   
00070   pos = format;
00071   while( (rt = parse_spec( &pos, &type ) ) == 0 ) {
00072     val.type = type;
00073     switch( type ) {
00074        case VAL_TYPE_UINT8:
00075          val.u.u8 = (uint8_t) va_arg( ap, int32_t );
00076          break;
00077       case VAL_TYPE_INT8:
00078          val.u.n8 = (int8_t) va_arg( ap, int32_t );
00079          break;
00080        case VAL_TYPE_UINT16:
00081          val.u.u16 = (uint16_t) va_arg( ap, uint32_t );
00082          break;
00083        case VAL_TYPE_INT16:
00084          val.u.n16 = (int16_t) va_arg( ap, int32_t );
00085          break;
00086        case VAL_TYPE_UINT32:
00087          val.u.u32 = va_arg( ap, uint32_t );
00088          break;
00089       case VAL_TYPE_INT32:
00090          val.u.n32 = va_arg( ap, int32_t );
00091          break;
00092       case VAL_TYPE_UINT64:
00093          val.u.u64 = va_arg( ap, uint64_t );
00094          break;
00095       case VAL_TYPE_INT64:
00096          val.u.n64 = va_arg( ap, int64_t );
00097          break;
00098       case VAL_TYPE_STRING:
00099       case VAL_TYPE_PTR:
00100          val.u.pval = va_arg( ap, void *  );
00101          break;
00102      }
00103      ARRAY_push_back( &values->values, &val, sizeof(val) );
00104   }
00105   va_end( ap );
00106   
00107   if (rt == -1) {
00108     return -1;
00109   }
00110   return 0; 
00111 }
00112 
00113 int VALUES_scanv( VALUES *values, const char *format, va_list ap )
00114 {
00115   VAL_TYPE type;
00116   VAL *val;
00117   size_t i;
00118   const char *pos;
00119   void *ptr;
00120   int rt;
00121 
00122   pos = format;
00123   for(i = 0; i < ARRAY_size(&values->values) && (rt = parse_spec( &pos, &type )) == 0; i++ ) {
00124      val = VALUES_at( values, i );
00125 
00126      if (val->type != type) {
00127        va_end(ap);
00128        return -1;
00129      }
00130 
00131      ptr = va_arg( ap, void *);
00132 
00133      switch( type ) {
00134        case VAL_TYPE_UINT8: 
00135          * ((uint8_t *) ptr) = val->u.u8;
00136          break;
00137        case VAL_TYPE_INT8:
00138          * ((int8_t *) ptr) = val->u.n8;
00139          break;
00140        case VAL_TYPE_UINT16:
00141          * ((uint16_t *) ptr) = val->u.u16;
00142          break;
00143        case VAL_TYPE_INT16:
00144          * ((int16_t *) ptr) = val->u.n16;
00145          break;
00146       case VAL_TYPE_UINT32:
00147          * ((uint32_t *) ptr) = val->u.u32;
00148          break;
00149       case VAL_TYPE_INT32:
00150          * ((int32_t *) ptr) = val->u.n32;
00151          break;
00152       case VAL_TYPE_UINT64:
00153          * ((uint64_t *) ptr) = val->u.u64;
00154          break;
00155       case VAL_TYPE_INT64:
00156          * ((int64_t *) ptr) = val->u.n64;
00157          break;
00158       case VAL_TYPE_STRING:
00159       case VAL_TYPE_PTR:
00160          * ((char **) ptr) = val->u.sval;
00161          break;
00162      }
00163   }
00164   va_end( ap );
00165 
00166   if (rt == -1) {
00167     return -1;
00168   }
00169   if (*pos != '\0') {
00170     return -1;
00171   }
00172   return 0;
00173 }
00174 
00175