e576bb2002-10-11Martin Nilsson /* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information.
b733792006-07-04Martin Stjernholm || $Id: pike_macros.h,v 1.40 2006/07/04 21:31:30 mast Exp $
e576bb2002-10-11Martin Nilsson */
24ddc71998-03-28Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe) #ifndef MACROS_H #define MACROS_H
bdfb861997-12-22Fredrik Hübinette (Hubbe) #include <global.h> #ifdef HAVE_SYS_PARAM_H
5267b71995-08-09Fredrik Hübinette (Hubbe) #include <sys/param.h>
bdfb861997-12-22Fredrik Hübinette (Hubbe) #endif
9aa6fa1997-05-19Fredrik Hübinette (Hubbe) #include "pike_memory.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) 
d2361e2003-06-30Martin Stjernholm #define PTR_TO_INT(PTR) ((size_t) ((char *) (PTR) - (char *) NULL))
bedbe72003-06-30Martin Stjernholm 
a147b62003-01-02Henrik Grubbström (Grubba) #define OFFSETOF(str_type, field) \
d2361e2003-06-30Martin Stjernholm  PTR_TO_INT(& (((struct str_type *)NULL)->field))
5267b71995-08-09Fredrik Hübinette (Hubbe) #define BASEOF(ptr, str_type, field) \
a147b62003-01-02Henrik Grubbström (Grubba)  ((struct str_type *)((char*)ptr - OFFSETOF(str_type, field)))
48f9382005-03-15Henrik Grubbström (Grubba) #ifdef __cplusplus extern "C++" { template<typename T> static inline int low_alignof_(T *ignored) { struct { char x; T y;} *bar = NULL; return PTR_TO_INT(&bar->y); } }; #define ALIGNOF(X) low_alignof_((X*)NULL) #else
a147b62003-01-02Henrik Grubbström (Grubba) #define ALIGNOF(X) OFFSETOF({ char ignored_; X fooo_;}, fooo_)
48f9382005-03-15Henrik Grubbström (Grubba) #endif
d2361e2003-06-30Martin Stjernholm /* #define ALIGNOF(X) PTR_TO_INT(&(((struct { char ignored_ ; X fooo_; } *)NULL)->fooo_)) */
5267b71995-08-09Fredrik Hübinette (Hubbe)  #define NELEM(a) (sizeof (a) / sizeof ((a)[0])) #define ALLOC_STRUCT(X) ( (struct X *)xalloc(sizeof(struct X)) ) #define MINIMUM(X,Y) ((X)<(Y)?(X):(Y)) #define MAXIMUM(X,Y) ((X)>(Y)?(X):(Y))
b432bb1996-10-29Per Hedbor 
559b5f2004-11-14Martin Stjernholm PMOD_EXPORT extern const char Pike_is8bitalnum_vector[]; #define is8bitalnum(X) (Pike_is8bitalnum_vector[((unsigned)(X))&0xff] == '1')
b432bb1996-10-29Per Hedbor  #define isidchar(X) is8bitalnum(X)
5c8e891995-10-29Fredrik Hübinette (Hubbe) 
94eb311998-05-18Henrik Grubbström (Grubba) #ifndef HAVE_ISGRAPH #define isgraph(X) (ispunct(X) || isupper(X) || islower(X) || isdigit(X)) #endif /* !HAVE_ISGRAPH */
5267b71995-08-09Fredrik Hübinette (Hubbe) 
1994981998-04-07Fredrik Hübinette (Hubbe) 
ee1fb82000-08-03Henrik Grubbström (Grubba) #define DO_ALIGN(X,Y) (((size_t)(X)+((Y)-1)) & -(Y))
45ee5d1999-02-10Fredrik Hübinette (Hubbe) #define CONSTANT_STRLEN(X) (sizeof(X) - sizeof(""))
ac3edc2000-06-27Henrik Grubbström (Grubba) #define SET_NEXT_AND_FREE(p,free_item) do{ \
fccf992000-04-07Fredrik Hübinette (Hubbe)  next=p->next; \ while(p->refs == 1 && (next=p->next)) \ { \ add_ref(next); \
ac3edc2000-06-27Henrik Grubbström (Grubba)  free_item(p); \
fccf992000-04-07Fredrik Hübinette (Hubbe)  p=next; \ } \
ac3edc2000-06-27Henrik Grubbström (Grubba)  free_item(p); \
fccf992000-04-07Fredrik Hübinette (Hubbe) }while(0)
a4033e2000-04-14Fredrik Hübinette (Hubbe) 
2bd0382000-12-14Martin Stjernholm /* This variant never leaves p pointing at a deallocated block, as the * one above can do. I.e. it frees a ref to the item p points at, and * sets p to the same or next item with references, or sets it to * zero. */
45af0d2001-05-13Fredrik Hübinette (Hubbe) /* how can SET_NEXT_AND_FREE leave *next* pointing to a deallocated block? * -Hubbe */
d20cf32001-07-20Martin Stjernholm /* Afaik it doesn't, but it leaves no value that is usable for the * purposes this macro was made for. /mast */
2bd0382000-12-14Martin Stjernholm #define FREE_AND_GET_REFERENCED(p, item_type, free_item) do { \ item_type *next; \ while (1) { \ if (p->refs > 1) { \ free_item(p); \ break; \ } \ if (!(next = p->next)) { \ free_item(p); \ p = 0; \ break; \ } \ add_ref(next); \ free_item(p); \ p = next; \ } \ } while (0)
a4033e2000-04-14Fredrik Hübinette (Hubbe) #define DOUBLELINK(first_object, o) do { \
08cf752001-10-06Fredrik Hübinette (Hubbe)  debug_malloc_touch(o); \
a4033e2000-04-14Fredrik Hübinette (Hubbe)  o->next=first_object; \ o->prev=0; \ if(first_object) first_object->prev=o; \ first_object=o; \ }while(0) #define DOUBLEUNLINK(first_object,o) do{ \
08cf752001-10-06Fredrik Hübinette (Hubbe)  debug_malloc_touch(o); \
a4033e2000-04-14Fredrik Hübinette (Hubbe)  if(o->prev) { \ o->prev->next=o->next; \ }else { \ DO_IF_DEBUG( \
08cf752001-10-06Fredrik Hübinette (Hubbe)  if(first_object != o) { \ describe(o); \
5aad932002-08-15Marcus Comstedt  Pike_fatal("Linked in wrong list!\n"); \
08cf752001-10-06Fredrik Hübinette (Hubbe)  } \
a4033e2000-04-14Fredrik Hübinette (Hubbe)  ) \ first_object=o->next; \ } \ \ if(o->next) o->next->prev=o->prev; \ }while(0)
f8153c2000-10-09Fredrik Hübinette (Hubbe) #define PIKE_XCONCAT(X,Y) PIKE_CONCAT(X,Y) #define PIKE_XCONCAT3(X,Y,Z) PIKE_CONCAT(X,Y,Z) #define PIKE_XCONCAT4(X,Y,Z,Q) PIKE_CONCAT(X,Y,Z,Q)
6b40372001-07-22Martin Stjernholm /* Useful to get a literal comma in an argument to a macro. */ #define COMMA ,
f8153c2000-10-09Fredrik Hübinette (Hubbe) 
b733792006-07-04Martin Stjernholm /* Necessary to pass an empty argument to a macro for some preprocessors. */ #define NOTHING
1f21332000-07-28Fredrik Hübinette (Hubbe) /* Needed for fsort_template.h */
6f0d752000-12-16Marcus Comstedt PMOD_EXPORT int my_log2(size_t x);
1f21332000-07-28Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif