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. */
24ddc71998-03-28Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe) #ifndef MACROS_H #define MACROS_H
cc3d8b2006-08-02Martin Stjernholm #include "global.h"
bdfb861997-12-22Fredrik Hübinette (Hubbe)  #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 
3946ea2011-05-02Per Hedbor #if __GNUC__ >= 4 # define OFFSETOF(T,X) __builtin_offsetof(struct T,X) # define ALIGNOF(X) __alignof__(X)
48f9382005-03-15Henrik Grubbström (Grubba) #else
3946ea2011-05-02Per Hedbor # define OFFSETOF(T, X) PTR_TO_INT(& (((struct T *)NULL)->X)) # define ALIGNOF(X) OFFSETOF({ char ignored_; X fooo_;}, fooo_)
48f9382005-03-15Henrik Grubbström (Grubba) #endif
3946ea2011-05-02Per Hedbor  #define BASEOF(ptr, str_type, field) \ ((struct str_type *)((char*)ptr - OFFSETOF(str_type, field)))
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')
13670c2015-05-25Martin Nilsson 
b432bb1996-10-29Per Hedbor #define isidchar(X) is8bitalnum(X)
5c8e891995-10-29Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe) 
1994981998-04-07Fredrik Hübinette (Hubbe) 
5a6d8e2006-07-05Martin Stjernholm #define DO_ALIGN(X,Y) (((size_t)(X)+((Y)-1)) & ~((Y)-1))
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
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif