su
1.12.11
|
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) */