Modules/UDI - GIO Metalanguage Binding, GIO UART support, init error handling
[tpg/acess2.git] / KernelLand / Modules / Interfaces / UDI / udi_lib / core / layout.c
index 97db27c..45f601b 100644 (file)
 #define _PUT(type,vtype) do{\
        ofs = alignto(ofs,type); \
        if(buf){\
-               *(type*)(buf+ofs) = va_arg(values,vtype);\
+               *(type*)(buf+ofs) = va_arg(*values,vtype);\
                LOG(#type" %p %x", buf+ofs, *(type*)(buf+ofs));\
        }\
-       else    va_arg(values,vtype); \
+       else if(values) \
+               va_arg(*values,vtype); \
        ofs += sizeof(type); \
 }while(0)
 
-size_t _udi_marshal_values(void *buf, udi_layout_t *layout, va_list values)
+size_t _udi_marshal_step(void *buf, size_t cur_ofs, const udi_layout_t **layoutp, va_list *values)
+{
+       size_t  ofs = cur_ofs;
+       const udi_layout_t      *layout = *layoutp;
+       switch(*layout++)
+       {
+       case UDI_DL_UBIT8_T:    _PUT(udi_ubit8_t, UDI_VA_UBIT8_T);      break;
+       case UDI_DL_SBIT8_T:    _PUT(udi_sbit8_t, UDI_VA_SBIT8_T);      break;
+       case UDI_DL_UBIT16_T:   _PUT(udi_ubit16_t, UDI_VA_UBIT16_T);    break;
+       case UDI_DL_SBIT16_T:   _PUT(udi_sbit16_t, UDI_VA_SBIT16_T);    break;
+       case UDI_DL_UBIT32_T:   _PUT(udi_ubit32_t, UDI_VA_UBIT32_T);    break;
+       case UDI_DL_SBIT32_T:   _PUT(udi_sbit32_t, UDI_VA_SBIT16_T);    break;
+       case UDI_DL_BOOLEAN_T:  _PUT(udi_boolean_t, UDI_VA_BOOLEAN_T);  break;
+       case UDI_DL_STATUS_T:   _PUT(udi_status_t, UDI_VA_STATUS_T);    break;
+       
+       case UDI_DL_INDEX_T:    _PUT(udi_index_t, UDI_VA_INDEX_T);      break;
+       
+       case UDI_DL_CHANNEL_T:  _PUT(udi_channel_t, UDI_VA_CHANNEL_T);  break;
+       case UDI_DL_ORIGIN_T:   _PUT(udi_origin_t, UDI_VA_ORIGIN_T);    break;
+
+       case UDI_DL_BUF:
+               _PUT(udi_buf_t*,UDI_VA_POINTER);
+               layout += 3;
+               break;
+       case UDI_DL_CB:
+               _PUT(udi_cb_t*,UDI_VA_POINTER);
+               break;
+       case UDI_DL_INLINE_UNTYPED:
+               _PUT(void*,UDI_VA_POINTER);
+               break;
+       case UDI_DL_INLINE_DRIVER_TYPED:
+               _PUT(void*,UDI_VA_POINTER);
+               break;
+       case UDI_DL_MOVABLE_UNTYPED:
+               _PUT(void*,UDI_VA_POINTER);
+               break;
+       
+       case UDI_DL_INLINE_TYPED:
+       case UDI_DL_MOVABLE_TYPED:
+               _PUT(void*,UDI_VA_POINTER);
+               while(*layout++ != UDI_DL_END)
+                       ;
+               break;
+
+       default:
+               Log_Error("UDI", "_udi_marshal_step - Unknown layout code %i", layout[-1]);
+               return 0;
+       }
+       *layoutp = layout;
+       return ofs;
+}
+
+size_t _udi_marshal_values(void *buf, const udi_layout_t *layout, va_list values)
 {
        size_t  ofs = 0;
        while( *layout != UDI_DL_END )
        {
-               switch(*layout++)
-               {
-               case UDI_DL_UBIT8_T:    _PUT(udi_ubit8_t, UDI_VA_UBIT8_T);      break;
-               case UDI_DL_SBIT8_T:    _PUT(udi_sbit8_t, UDI_VA_SBIT8_T);      break;
-               case UDI_DL_UBIT16_T:   _PUT(udi_ubit16_t, UDI_VA_UBIT16_T);    break;
-               case UDI_DL_SBIT16_T:   _PUT(udi_sbit16_t, UDI_VA_SBIT16_T);    break;
-               case UDI_DL_UBIT32_T:   _PUT(udi_ubit32_t, UDI_VA_UBIT32_T);    break;
-               case UDI_DL_SBIT32_T:   _PUT(udi_sbit32_t, UDI_VA_SBIT16_T);    break;
-               case UDI_DL_BOOLEAN_T:  _PUT(udi_boolean_t, UDI_VA_BOOLEAN_T);  break;
-               case UDI_DL_STATUS_T:   _PUT(udi_status_t, UDI_VA_STATUS_T);    break;
-               
-               case UDI_DL_INDEX_T:    _PUT(udi_index_t, UDI_VA_INDEX_T);      break;
-               
-               case UDI_DL_CHANNEL_T:  _PUT(udi_channel_t, UDI_VA_CHANNEL_T);  break;
-               case UDI_DL_ORIGIN_T:   _PUT(udi_origin_t, UDI_VA_ORIGIN_T);    break;
-               
-               default:
-                       Log_Error("UDI", "_udi_marshal_values - Unknown layout code %i", layout[-1]);
-                       return -1;
-               }
+               ofs = _udi_marshal_step(buf, ofs, &layout, &values);
+               if( ofs == 0 )
+                       return 0;
        }
        return ofs;
 }

UCC git Repository :: git.ucc.asn.au