The outage for Sunday 24th November has been cancelled.
Bioplib
Protein Structure C Library
Main Page
Related Pages
Data Structures
Files
File List
Globals
All
Data Structures
Files
Functions
Variables
Typedefs
Macros
Pages
src
macros.h
Go to the documentation of this file.
1
/************************************************************************/
2
/**
3
4
\file macros.h
5
6
\version V2.26
7
\date 14.12.16
8
\brief Useful macros
9
10
\copyright (c) Dr. Andrew C.R. Martin / UCL 1991-2016
11
\author Dr. Andrew C. R. Martin
12
\par
13
Institute of Structural & Molecular Biology,
14
University College London,
15
Gower Street,
16
London.
17
WC1E 6BT.
18
\par
19
andrew@bioinf.org.uk
20
andrew.martin@ucl.ac.uk
21
22
**************************************************************************
23
24
This code is NOT IN THE PUBLIC DOMAIN, but it may be copied
25
according to the conditions laid out in the accompanying file
26
COPYING.DOC.
27
28
The code may be modified as required, but any modifications must be
29
documented so that the person responsible can be identified.
30
31
The code may not be sold commercially or included as part of a
32
commercial product except as described in the file COPYING.DOC.
33
34
**************************************************************************
35
36
Description:
37
============
38
39
If not Amiga defines abs().
40
Defines max(), min() and PI if not done.
41
Defines list handling macros.
42
Defines newline() and toggle() macros.
43
44
**************************************************************************
45
46
Usage:
47
======
48
49
**************************************************************************
50
51
Revision History:
52
=================
53
- V1.0 06.02.91 Original
54
- V1.1 15.02.91 Moved PI definition to non-Amiga's only
55
- V1.2 21.03.91 Added RANGECHECK
56
- V1.3 06.09.91 Added DIST, DISTSQ and Vec3f
57
- V1.4 09.09.91 Fixed multi-command macros with {}
58
- V1.5 24.01.92 Fixed for 32 bit addresses and added malloc checks.
59
- V1.6 03.04.92 Small change to ALLOCNEXT and ALLOCNEXTPREV, so
60
will do a NEXT() even if malloc() fails.
61
- V1.7 06.05.92 Added TERMINATE()
62
- V1.8 06.07.92 Added MAX(), MIN() and ABS()
63
- V1.9 22.07.92 Fixed ABS()
64
- V1.10 28.09.92 Added TRUE & FALSE and UPPER()
65
- V1.11 03.11.92 Changed TOGGLE and newline is now upper case.
66
- V1.12 16.11.92 Added KILLLEADSPACES()
67
- V1.13 18.11.92 Fixed UPPER() for MicrosoftC which returns strlen()
68
as unsigned
69
- V1.14 20.11.92 ABS() now uses 0 rather than 0.0, so we don't
70
try to use floats with ints...
71
- V2.0 24.11.92 Removed all small letter macros
72
- V2.1 12.07.93 Added double include check, moved math definitions
73
to MathType.h and added LOWER()
74
- V2.2 07.10.93 UPPER() and LOWER() check case first for ESV
75
compatibility
76
- V2.3 23.05.94 Added D(BUG)
77
- V2.4 14.07.94 Added do{}while(0) bracketing of all multi-line macros
78
- V2.5 21.11.94 ABS, MAX and MIN check that they're not already defined
79
- V2.6 16.02.95 Added DELETE()
80
- V2.7 21.02.95 Updated some internal variable names
81
- V2.8 02.08.95 Added TESTINARRAY(), FINDINARRAY(),
82
SET(), UNSET() and ISSET()
83
- V2.9 20.11.95 Added TERMAT()
84
- V2.10 06.02.96 Added KILLTRAILSPACES()
85
- V2.11 14.06.96 Added PROMPT()
86
- V2.12 23.07.96 Added PADMINTERM()
87
- V2.13 19.09.96 Include ctype for UPPER() etc
88
- V2.14 13.03.99 Added DELETEDOUBLE()
89
- V2.15 01.03.01 Added DOTIFY() DEDOTIFY() PADCHARMINTERM() SUBSCHAR()
90
- V2.16 25.01.06 Added FINDPREV()
91
- V2.17 10.04.08 Fixed bug in DELETE() - the break was not properly
92
stopping prev from being changed
93
- V2.18 29.04.14 Added DEPRECATED() By: CTP
94
- V2.19 07.05.14 Moved DEPRECATED() to deprecated.h By: CTP
95
- V2.20 07.07.14 Use bl prefix for functions - change padterm() to
96
blPadterm() By: CTP
97
- V2.21 24.07.14 Initialize list pointers for DELETE macro. By: CTP
98
- V2.22 25.02.15 LAST() is now safe if the pointer is NULL
99
- V2.23 26.06.15 Added STRNCPYNOSPACES(out, in, mx)
100
- V2.24 28.08.15 Added FREE()
101
- V2.25 04.11.15 Added FCLOSE()
102
- V2.26 14.12.16 Added TERMINATECR()
103
104
*************************************************************************/
105
/* Doxygen
106
-------
107
#GROUP General Programming
108
#SUBGROUP Handling linked lists
109
110
#FUNCTION INIT(x,y)
111
Macro: Initialise list of name x and type y. Set x->next to NULL
112
#FUNCTION INITPREV(x,y)
113
Macro: Initialise list of name x and type y.
114
Set x->next and x->prev to NULL
115
#FUNCTION NEXT(x)
116
Macro: Step on in linked list
117
#FUNCTION PREV(x)
118
Macro: Step back in doubly linked list
119
#FUNCTION ALLOCNEXT(x,y)
120
Macro: Allocate next item in list and step on
121
#FUNCTION ALLOCNEXTPREV(x,y)
122
Macro: Allocate next item in doubly linked list and step on.
123
#FUNCTION LAST(x)
124
Macro: Move to end of list
125
#FUNCTION FREELIST(y,z)
126
Macro: Free list y of type z
127
#FUNCTION FREE(x)
128
Macro: Free memory if non-NULL and set the variable to NULL
129
#FUNCTION DELETE(lst,itm,type)
130
Macro: Deletes (itm) from linked list (lst) of type (type)
131
#FUNCTION FINDPREV(p, start, q)
132
Set p to item in linked list start before q
133
#FUNCTION DELETEDOUBLE(lst,itm,type)
134
Macro: Deletes (itm) from a doubly linked list (lst) of type (type)
135
136
#SUBGROUP Miscellaneous
137
#FUNCTION NEWLINE
138
Macro: Print a newline character to stdout
139
#FUNCTION RANGECHECK(x,y,z)
140
Macro: Return x constrained to range y to z
141
142
#SUBGROUP Flags and bitwise operations
143
#FUNCTION TOGGLE(x)
144
Macro: Toggle a flag
145
#FUNCTION SET(x,y)
146
Macro: Sets bit y (a hex value) in variable x
147
#FUNCTION UNSET(x,y)
148
Macro: Clears bit y (a hex value) in variable x
149
#FUNCTION ISSET(x,y)
150
Macro: Tests bit y (a hex value) in variable x
151
152
#SUBGROUP String handling
153
#FUNCTION TERMINATE(x)
154
Macro: Terminate a string at the first \n
155
#FUNCTION TERMINATECR(x)
156
Macro: Terminate a string at the first \r
157
#FUNCTION UPPER(x)
158
Macro: Converts a string to upper case
159
#FUNCTION KILLLEADSPACES(x,y)
160
Macro: Makes x a pointer into string y after any spaces or tabs.
161
#FUNCTION TERMAT(x,y)
162
Macro: Terminates character string x at first character y
163
#FUNCTION KILLTRAILSPACES(x)
164
Macro: Terminate string to remove any trailing white space
165
#FUNCTION PADMINTERM(str,len)
166
Macro: Pads a string to len chars only if it is shorter
167
#FUNCTION PADCHARMINTERM(str,char,len)
168
Macro: Pads a string to len chars with specified
169
character only if it is shorter
170
#FUNCTION DOTIFY(str)
171
Macro: Replace ' ' with '.' in string
172
#FUNCTION DEDOTIFY(str)
173
Macro: Replace '.' with ' ' in string
174
#FUNCTION STRNCPYNOSPACES(out, in, maxlen)
175
Macro: Like strncpy() but skips spaces
176
177
#SUBGROUP Maths
178
#FUNCTION MAX(x,y)
179
Macro: max() as macro
180
#FUNCTION MIN(x,y)
181
Macro: min() as macro
182
#FUNCTION ABS(x,y)
183
Macro: abs() as macro
184
185
#SUBGROUP Debugging
186
#FUNCTION D(BUG)
187
Macro: Prints the BUG string if DEBUG is defined first
188
189
#SUBGROUP Array handling
190
#FUNCTION TESTINARRAY(x,l,y,r)
191
Macro: Tests whether value (y) is in array (x) if length (l) returning the result in (r)
192
#FUNCTION FINDINARRAY(x,l,y,r)
193
Macro: Finds value (y) is in array (x) if length
194
(l) returning the offset in (r). Offset is -1 if not found
195
196
#SUBGROUP User interaction
197
#FUNCTION PROMPT(fp,x)
198
Macro: Issue a prompt to stdout if fp is a terminal
199
200
#SUBGROUP File handling
201
#FUNCTION FCLOSE(fp)
202
Macro: close a file pointer if it is non-NULL and not stdin/out/err.
203
Set the file pointer to NULL afterwards
204
205
*/
206
/************************************************************************/
207
#ifndef _MACROS_H
208
#define _MACROS_H
209
210
/***************************** Includes *********************************/
211
#include <ctype.h>
212
213
/**************************** Definitions *******************************/
214
#ifndef PI
215
#define PI (4.0 * atan(1.0))
216
#endif
217
218
#ifndef TRUE
219
#define TRUE 1
220
#endif
221
222
#ifndef FALSE
223
#define FALSE 0
224
#endif
225
226
/***************************** Maths macros *****************************/
227
#define RANGECHECK(x,y,z) ((x)<(y)) ? (y) : ((x)>(z)) ? (z) : (x)
228
#define DISTSQ(a,b) (((a)->x - (b)->x) * ((a)->x - (b)->x) + \
229
((a)->y - (b)->y) * ((a)->y - (b)->y) + \
230
((a)->z - (b)->z) * ((a)->z - (b)->z))
231
#define DIST(a,b) sqrt(((a)->x - (b)->x) * ((a)->x - (b)->x) + \
232
((a)->y - (b)->y) * ((a)->y - (b)->y) + \
233
((a)->z - (b)->z) * ((a)->z - (b)->z))
234
#ifndef ABS
235
#define ABS(x) (((x)<0) ? (-(x)) : (x))
236
#endif
237
238
#ifndef MAX
239
#define MAX(a,b) (((a)>(b)) ? (a) : (b))
240
#define MIN(a,b) (((a)<(b)) ? (a) : (b))
241
#endif
242
243
/***************************** List macros ******************************/
244
#define INIT(x,y) do { x=(y *)malloc(sizeof(y)); \
245
if(x != NULL) x->next = NULL; } while(0)
246
#define INITPREV(x,y) do { x=(y *)malloc(sizeof(y));\
247
if(x != NULL) {x->next=NULL; x->prev=NULL;} } \
248
while(0)
249
#define NEXT(x) (x)=(x)->next
250
#define PREV(x) (x)=(x)->prev
251
#define ALLOCNEXT(x,y) do { (x)->next=(y *)malloc(sizeof(y));\
252
if((x)->next != NULL) { (x)->next->next=NULL; }\
253
NEXT(x); } while(0)
254
#define ALLOCNEXTPREV(x,y) do { (x)->next=(y *)malloc(sizeof(y));\
255
if((x)->next != NULL)\
256
{ (x)->next->prev = (x); \
257
(x)->next->next=NULL; }\
258
NEXT(x);} while(0)
259
#define LAST(x) while(((x)!=NULL) && ((x)->next != NULL)) NEXT(x)
260
/* FREELIST takes 2 parameters:
261
y: name of list
262
z: type of list
263
*/
264
#define FREELIST(y,z) while((y)!=NULL) \
265
{ z *_freelist_macro_q; \
266
_freelist_macro_q = (y)->next; \
267
free((char *)(y)); \
268
(y) = _freelist_macro_q; \
269
}
270
#define FREE(x) if((x)!=NULL) free(x); (x) = NULL
271
272
/*>DELETE(start, item, type)
273
-------------------------
274
Deletes (item) from a linked list.
275
(start) will be modified if (item) is the first in the list.
276
(item) is returned as the pointer to the next item in the list (i.e.
277
as item->next). One can therefore simply call the routine N times
278
to delete N items. If (start) or (item) is NULL, does nothing
279
280
- 16.02.95 Original By: ACRM
281
- 10.04.08 Fixed position of break. By: CTP
282
- 24.07.14 Initialize list pointers. By: CTP
283
*/
284
#define DELETE(x, y, z) \
285
do { \
286
z *_delete_macro_p = NULL, \
287
*_delete_macro_prev = NULL, \
288
*_delete_macro_temp = NULL, \
289
*_delete_macro_temp2 = NULL; \
290
if((x)!=NULL && (y)!=NULL) \
291
{ \
292
for(_delete_macro_p=(x); \
293
_delete_macro_p!=NULL; \
294
NEXT(_delete_macro_p)) \
295
{ \
296
if(_delete_macro_p == (y)) \
297
{ \
298
_delete_macro_temp2 = (y)->next; \
299
if(_delete_macro_prev == NULL) \
300
{ \
301
_delete_macro_temp = (x)->next; \
302
free(x); \
303
(x) = _delete_macro_temp; \
304
} \
305
else \
306
{ \
307
_delete_macro_prev->next = _delete_macro_p->next; \
308
free(_delete_macro_p); \
309
} \
310
break; \
311
} \
312
_delete_macro_prev = _delete_macro_p; \
313
} \
314
(y) = _delete_macro_temp2; \
315
} \
316
} while(FALSE)
317
318
319
/*>DELETEDOUBLE(start, item, type)
320
-------------------------------
321
Deletes (item) from a doubly linked list.
322
(start) will be modified if (item) is the first in the list.
323
(item) is returned as the pointer to the next item in the list (i.e.
324
as item->next). One can therefore simply call the routine N times
325
to delete N items. If (start) or (item) is NULL, does nothing
326
327
- 13.03.99 Original By: ACRM
328
*/
329
#define DELETEDOUBLE(s, x, y) \
330
do { y *_deleteandnext_macro_temp; \
331
if(((s)!=NULL) && ((x)!=NULL)) \
332
{ if((x)==(s)) (s) = (x)->next; \
333
_deleteandnext_macro_temp = (x)->next; \
334
if((x)->prev != NULL) (x)->prev->next = (x)->next; \
335
if((x)->next != NULL) (x)->next->prev = (x)->prev; \
336
free(x); \
337
(x) = _deleteandnext_macro_temp; \
338
} } while(0)
339
340
/*>FINDPREV(ptr, start, item)
341
--------------------------
342
Searches a linked list beginning at (start) to find the item which
343
preceeds (item). Its address is put into (ptr). If (item) is the
344
same as (start) or (item) is not found, then the routine returns
345
NULL in (ptr)
346
This is used when wanting to look at the previous item in a singly
347
linked list.
348
349
- 26.01.06 Original By: ACRM
350
*/
351
#define FINDPREV(p, s, l) \
352
do { p = (s); \
353
if((s)==(l)) \
354
{ p = NULL; } else \
355
{ \
356
while((p != NULL) && (p->next != (l))) \
357
{ p = p->next; \
358
} } } while(0)
359
360
361
/***************************** Misc. macros *****************************/
362
#define NEWLINE printf("\n")
363
364
#define TOGGLE(x) (x) = (x) ? FALSE : TRUE
365
366
#define TERMINATE(x) do { int _terminate_macro_j; \
367
for(_terminate_macro_j=0; \
368
(x)[_terminate_macro_j]; \
369
_terminate_macro_j++) \
370
{ if((x)[_terminate_macro_j] == '\n') \
371
{ (x)[_terminate_macro_j] = '\0'; \
372
break; \
373
} } } while(0)
374
#define TERMINATECR(x) do { int _terminate_macro_j; \
375
for(_terminate_macro_j=0; \
376
(x)[_terminate_macro_j]; \
377
_terminate_macro_j++) \
378
{ if((x)[_terminate_macro_j] == '\r') \
379
{ (x)[_terminate_macro_j] = '\0'; \
380
break; \
381
} } } while(0)
382
#define TERMAT(x, y) do { int _termat_macro_j; \
383
for(_termat_macro_j=0; \
384
(x)[_termat_macro_j]; \
385
_termat_macro_j++) \
386
{ if((x)[_termat_macro_j] == (y)) \
387
{ (x)[_termat_macro_j] = '\0'; \
388
break; \
389
} } } while(0)
390
#define UPPER(x) do { int _upper_macro_i; \
391
for(_upper_macro_i=0; \
392
_upper_macro_i<(int)strlen(x) && \
393
(x)[_upper_macro_i]; \
394
_upper_macro_i++) \
395
if(islower((x)[_upper_macro_i])) \
396
(x)[_upper_macro_i] = \
397
(char)toupper((x)[_upper_macro_i]); \
398
} while(0)
399
#define LOWER(x) do { int _lower_macro_i; \
400
for(_lower_macro_i=0; \
401
_lower_macro_i<(int)strlen(x) && \
402
(x)[_lower_macro_i]; \
403
_lower_macro_i++) \
404
if(isupper((x)[_lower_macro_i])) \
405
(x)[_lower_macro_i] = \
406
(char)tolower((x)[_lower_macro_i]); \
407
} while(0)
408
#define KILLLEADSPACES(y,x) \
409
do \
410
{ for((y)=(x); *(y) == ' ' || *(y) == '\t'; (y)++) ; } \
411
while(0)
412
413
414
#define KILLTRAILSPACES(x) \
415
do { int _kts_macro_i; \
416
_kts_macro_i = strlen(x) - 1; \
417
while(((x)[_kts_macro_i] == ' ' || \
418
(x)[_kts_macro_i] == '\t') && \
419
_kts_macro_i>=0) \
420
(_kts_macro_i)--; \
421
(x)[++(_kts_macro_i)] = '\0'; \
422
} while(0)
423
424
425
/* Tests for the presence of (y) in array (x) of length (l). The result
426
(TRUE or FALSE) is returned in (r)
427
- 02.08.95 Original
428
*/
429
#define TESTINARRAY(x, l, y, r) \
430
do { \
431
int _inarray_macro_i; \
432
(r) = FALSE; \
433
if((x)==NULL) break; \
434
for(_inarray_macro_i=0; _inarray_macro_i<(l); _inarray_macro_i++) \
435
{ if((x)[_inarray_macro_i] == (y)) \
436
{ (r) = TRUE; \
437
break; \
438
} } } while(FALSE)
439
440
/* Finds offset of item (y) in array (x) of length (l). The result
441
is returned in (r) which is -1 if item not found
442
- 02.08.95 Original
443
*/
444
#define FINDINARRAY(x, l, y, r) \
445
do { \
446
int _inarray_macro_i; \
447
(r) = (-1); \
448
if((x)==NULL) break; \
449
for(_inarray_macro_i=0; _inarray_macro_i<(l); _inarray_macro_i++) \
450
{ if((x)[_inarray_macro_i] == (y)) \
451
{ (r) = _inarray_macro_i; \
452
break; \
453
} } } while(FALSE)
454
455
456
/* Used just like padterm, but doesn't touch the string if it's already
457
longer than len characters
458
*/
459
#define PADMINTERM(string, len) \
460
do { \
461
if(strlen((string)) < (len)) blPadterm((string), (len)); \
462
} while(0)
463
464
/************************************************************************/
465
/*>PADCHARMINTERM(string, char, length)
466
------------------------------------
467
*/
/**
468
469
Pads a string to a specified length using char and terminates at that
470
point
471
472
- 13.03.99 Original By: ACRM
473
*/
474
#define PADCHARMINTERM(s, c, l) \
475
do { int _padminterm_macro_i; \
476
if(strlen((s)) < (l)) \
477
{ for(_padminterm_macro_i=strlen((s)); \
478
_padminterm_macro_i<(l); \
479
_padminterm_macro_i++) \
480
(s)[_padminterm_macro_i] = (c); \
481
(s)[(l)] = '\0'; \
482
} } while(0)
483
484
485
/************************************************************************/
486
/*>DOTIFY(char *str)
487
-----------------
488
*/
/**
489
490
Macro to replace ' ' in a string with '.'
491
492
- 21.04.99 Original By: ACRM
493
*/
494
#define DOTIFY(str) \
495
do { \
496
char *_dotify_macro_chp; \
497
_dotify_macro_chp = str; \
498
while(*_dotify_macro_chp) { \
499
if(*_dotify_macro_chp==' ') *_dotify_macro_chp = '.'; \
500
_dotify_macro_chp++; \
501
} } while(0)
502
503
/************************************************************************/
504
/*>DEDOTIFY(char *str)
505
-------------------
506
*/
/**
507
508
Macro to replace '.' in a string with ' '
509
510
- 21.04.99 Original By: ACRM
511
*/
512
#define DEDOTIFY(str) \
513
do { \
514
char *_dedotify_macro_chp; \
515
_dedotify_macro_chp = str; \
516
while(*_dedotify_macro_chp) { \
517
if(*_dedotify_macro_chp=='.') *_dedotify_macro_chp = ' '; \
518
_dedotify_macro_chp++; \
519
} } while(0)
520
521
522
/************************************************************************/
523
/*>SUBSCHAR(s, x, y)
524
-----------------
525
*/
/**
526
527
Substitute character x by character y in string s
528
529
- 21.05.99 Original
530
*/
531
#define SUBSCHAR(s, x, y) \
532
do { char *_subschar_macro_ch = (s); \
533
while(*_subschar_macro_ch != '\0') \
534
{ if(*_subschar_macro_ch == (x)) *_subschar_macro_ch = (y); \
535
_subschar_macro_ch++; \
536
} } while(0)
537
538
539
/************************************************************************/
540
#define STRNCPYNOSPACES(out, in, mx) \
541
do { char *_chp; \
542
int _pos = 0; \
543
for(_chp=(in); *_chp != '\0'; _chp++) \
544
{ if(*_chp != ' ') \
545
{ buffer[_pos++] = *_chp; \
546
if(_pos >= (mx)) break; \
547
} } \
548
if(_pos < (mx)) buffer[_pos] = '\0'; \
549
} while(0)
550
551
552
/* Bit-wise operators
553
- 02.08.95 Original
554
*/
555
#define SET(x, y) (x) |= (y)
556
#define UNSET(x, y) (x) &= (~(y))
557
#define ISSET(x, y) ((BOOL)((x)&(y)))
558
559
/* A version of fclose() that checks the file pointer is non-NULL and
560
not standard in/out/err. After closing the file, it sets the file
561
pointer to NULL
562
04.11.15 Original By: ACRM
563
*/
564
#define FCLOSE(x) \
565
do { \
566
if(((x) != NULL) && ((x) != stdin) && \
567
((x) != stdout) && ((x) != stderr)) { \
568
fclose((x)); \
569
(x) = NULL; \
570
} \
571
} while (0)
572
573
#ifdef DEBUG
574
#define D(BUG) fprintf(stderr,"%s",BUG); fflush(stderr)
575
#else
576
#define D(BUG)
577
#endif
578
579
580
/************************** The PROMPT macro ****************************/
581
/* isatty() is not POSIX */
582
#ifdef __unix
583
# if defined(_POSIX_SOURCE) || !defined(_SVR4_SOURCE)
584
#include <unistd.h>
585
# endif
586
#endif
587
588
/* Default is just to print a string as a prompt */
589
#define PROMPT(in,x) printf("%s",(x))
590
591
/* More intelligent prompts for systems where we know the FILE structure*/
592
#ifdef __sgi
593
# undef PROMPT
594
# define PROMPT(in,x) do{if(isatty((in)->_file)) \
595
printf("%s",(x));}while(0)
596
#endif
597
#ifdef __linux__
598
# undef PROMPT
599
# define PROMPT(in,x) do{if(isatty((in)->_fileno)) \
600
printf("%s",(x));}while(0)
601
#endif
602
603
#endif
/* _MACROS_H */
604
Generated on Tue Oct 24 2017 10:57:11 for Bioplib by
1.8.8