su  1.12.11
sofia-sip/su_tagarg.h
Go to the documentation of this file.
00001 /*
00002  * This file is part of the Sofia-SIP package
00003  *
00004  * Copyright (C) 2005 Nokia Corporation.
00005  *
00006  * Contact: Pekka Pessi <pekka.pessi@nokia-email.address.hidden>
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public License
00010  * as published by the Free Software Foundation; either version 2.1 of
00011  * the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
00021  * 02110-1301 USA
00022  *
00023  */
00024 
00025 #ifndef SU_TAGARG_H
00026 
00027 #define SU_TAGARG_H
00028 
00037 #ifndef SU_TAG_H
00038 #include <sofia-sip/su_tag.h>
00039 #endif
00040 
00041 SOFIA_BEGIN_DECLS
00042 
00080 typedef struct {
00081   tagi_t  tl[2];
00082   va_list ap;
00083 } ta_list;
00084 
00085 #if defined(va_copy)
00086 #define su_va_copy(dst, src) va_copy((dst), (src))
00087 #elif defined(__va_copy)
00088 #define su_va_copy(dst, src) __va_copy((dst), (src))
00089 #else
00090 #define su_va_copy(dst, src) (memcpy(&(dst), &(src), sizeof (va_list)))
00091 #endif
00092 
00105 #if SU_HAVE_TAGSTACK
00106 /* All arguments are saved into stack (left-to-right) */
00107 #define ta_start(ta, t, v)                                              \
00108    do {                                                                 \
00109     tag_type_t ta_start__tag = (t); tag_value_t ta_start__value = (v);  \
00110     va_start((ta).ap, (v));                                             \
00111     while ((ta_start__tag) == tag_next && (ta_start__value) != 0) {     \
00112       ta_start__tag = ((tagi_t *)ta_start__value)->t_tag;               \
00113       if (ta_start__tag == tag_null || ta_start__tag == NULL)           \
00114         break;                                                          \
00115       if (ta_start__tag == tag_next) {                                  \
00116         ta_start__value = ((tagi_t *)ta_start__value)->t_value; }       \
00117       else {                                                            \
00118         ta_start__tag = tag_next;                                       \
00119         break;                                                          \
00120       }                                                                 \
00121     }                                                                   \
00122     (ta).tl->t_tag = ta_start__tag; (ta).tl->t_value = ta_start__value; \
00123     if (ta_start__tag != NULL &&                                        \
00124         ta_start__tag != tag_null &&                                    \
00125         ta_start__tag != tag_next) {                                    \
00126       (ta).tl[1].t_tag = tag_next;                                      \
00127       (ta).tl[1].t_value = (tag_value_t)(&(v) + 1);                     \
00128     } else {                                                            \
00129       (ta).tl[1].t_tag = 0; (ta).tl[1].t_value = (tag_value_t)0;        \
00130     }                                                                   \
00131   } while(0)
00132 #else
00133 /* Tagged arguments are in registers - copy all of them. */
00134 #define ta_start(ta, t, v)                                              \
00135    do {                                                                 \
00136     tag_type_t ta_start__tag = (t); tag_value_t ta_start__value = (v);  \
00137     va_start((ta).ap, (v));                                             \
00138     while ((ta_start__tag) == tag_next && (ta_start__value) != 0) {     \
00139       ta_start__tag = ((tagi_t *)ta_start__value)->t_tag;               \
00140       if (ta_start__tag == tag_null || ta_start__tag == NULL)           \
00141         break;                                                          \
00142       if (ta_start__tag == tag_next) {                                  \
00143         ta_start__value = ((tagi_t *)ta_start__value)->t_value;         \
00144       } else {                                                          \
00145         ta_start__tag = tag_next;                                       \
00146         break;                                                          \
00147       }                                                                 \
00148     }                                                                   \
00149     (ta).tl->t_tag = ta_start__tag; (ta).tl->t_value = ta_start__value; \
00150     if (ta_start__tag != NULL &&                                        \
00151         ta_start__tag != tag_null &&                                    \
00152         ta_start__tag != tag_next) {                                    \
00153       va_list ta_start__ap;                                             \
00154       su_va_copy(ta_start__ap, (ta).ap);                                \
00155       (ta).tl[1].t_tag = tag_next;                                      \
00156       (ta).tl[1].t_value = (tag_value_t)tl_vlist(ta_start__ap);         \
00157       va_end(ta_start__ap);                                             \
00158     } else {                                                            \
00159       (ta).tl[1].t_value = 0; (ta).tl[1].t_value = (tag_value_t)0;      \
00160     }                                                                   \
00161   } while(0)
00162 #endif
00163 
00170 #define ta_args(ta) (ta).tl
00171 
00179 #define ta_tags(ta) \
00180   (ta).tl[0].t_tag, (ta).tl[0].t_value, (ta).tl[1].t_tag, (ta).tl[1].t_value
00181 
00191 #if SU_HAVE_TAGSTACK
00192 #define ta_end(ta) (va_end((ta).ap), (ta).tl->t_tag = NULL, 0)
00193 #else
00194 #define ta_end(ta)                                         \
00195   ((((ta).tl[1].t_value) ?                                 \
00196     (tl_vfree((tagi_t *)((ta).tl[1].t_value))) : (void)0), \
00197    (ta).tl[1].t_value = 0, va_end((ta).ap), 0)
00198 #endif
00199 
00200 SOFIA_END_DECLS
00201 
00202 #endif /* !defined(SU_TAGARG_H) */
 All Data Structures Files Functions Variables Typedefs Enumerator Defines

Sofia-SIP 1.12.11 - Copyright (C) 2006 Nokia Corporation. All rights reserved. Licensed under the terms of the GNU Lesser General Public License.