├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── README.md ├── macros.h └── test.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.out -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | 2 | language: c 3 | 4 | compiler: gcc 5 | 6 | script: make 7 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contribute 2 | 3 | First off, thank you very much for considering contributing to macros.h. 4 | 5 | A good Macro is : Portable, safe, involves as less arbitrary variables as possible. Although I am trying my best, there might be some exception errors, please correct if you find any. Also, if I missed some other interesting macros, please contribute to make this collection complete and more usable. 6 | 7 | ### Conventions 8 | 9 | 1. All macros are in UPPERCASE. 10 | 2. In case of any Boolean Macro, the `IS_ prefix` should be used. For example, `IS_EVEN(x)`. And they should return a `1` or `0` value. 11 | 3. Macros for loops and conditionals should not end with braces so that the user can have the option for single line as well as block style. 12 | 4. A helper macro, which are expanded by some other main macro, usually they are not intended to be used directly. So they should be mentioned with their expansion level as prefix. For example, `PASTE(a,b)` expands into `PASTE2(a,b)` which further expands into `a##b`. 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Shubham Ramdeo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for GNU make 2 | 3 | CC = gcc 4 | 5 | all: build-test 6 | 7 | # do not use C89, see https://stackoverflow.com/a/2855148/9373031 8 | build-%: 9 | $(CC) -ansi -std=c99 $*.c -o $*.out -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 |


#macros.h

Useful C #macros
3 | 4 |

5 | 6 | 11 | This is a collection of commonly used C Macros I found on internet, and as suggested by my friends. 12 | 13 | ## Why this is awesome 14 | 15 | Using C Macros, we can extend C with a lot of useful functionality. For example, we can create loops like foreach which are very useful and handy when it comes to arrays. These are available in most of high level languages but not in C. But we got macros in C and so we can add on our own! 16 | 17 | ### How to use 18 | 19 | Just download macros.h from [here](https://github.com/ramdeoshubham/macros/archive/master.zip) and include it to the top. 20 | 21 | ```C 22 | #include "macros.h" 23 | ``` 24 | 25 | Note that there is an `ASSERT` macro useful for debugging purposes. To enable it, you need to `#define DEBUG` before including `macros.h`. 26 | 27 | # Available macros 28 | 29 | ### Boolean 30 | 31 | - TRUE 32 | - FALSE 33 | 34 | We get `TRUE` as `1` and `FALSE` as `0`. 35 | 36 | ```C 37 | while (TRUE) { 38 | if( (x > 5) == FALSE ) break; 39 | x++; printf("hi "); 40 | } 41 | ``` 42 | 43 | ### Operators 44 | 45 | - AND 46 | - OR 47 | - NOT 48 | - NOTEQUALS 49 | - EQUALS 50 | - IS 51 | 52 | These can be used to perform logical operations more conveniently. Specially, `==` is `EQUALS` and `=` is `IS`. So the age old confusion gets clear here. 53 | 54 | ```C 55 | x = 5; 56 | if( x EQUALS 0 OR x > 10 AND x NOTEQUALS 15) 57 | { 58 | x IS 1; 59 | } 60 | else if ( NOT (x > 0) ) { 61 | x IS 0; 62 | } 63 | else x IS 100; 64 | printf("\n%d\n",x); 65 | ``` 66 | 67 | ### Loops 68 | 69 | - FOREVER 70 | 71 | A simple infinite loop. It needs to be break from the scope to stop it. 72 | 73 | ```C 74 | FOREVER{ 75 | if( x > 5 ) break; 76 | x++;printf("hi "); 77 | } 78 | ``` 79 | 80 | - RANGE (var, from, to) 81 | 82 | A simple from - to ranged loop. 83 | 84 | ```C 85 | int i; 86 | RANGE (i, 10, 20){ 87 | printf("%d ", i); 88 | } 89 | 90 | /* OUTPUT: 91 | 10 11 12 13 14 15 16 17 18 19 20 */ 92 | ``` 93 | 94 | It works in both direction way without any modifications required. It will decide on its on when to decrement or increment. Its smart isn't it? 95 | 96 | ```C 97 | int i; 98 | RANGE (i, 5, -5){ 99 | printf("%d ", i); 100 | } 101 | 102 | /* OUTPUT: 103 | 5 4 3 2 1 0 -1 -2 -3 -4 -5 */ 104 | ``` 105 | 106 | - FOREACH (item, array) 107 | 108 | A C implementation of foreach loop, it will go through each element of an array, and will perform operations on each element as returned into pointer item variable. 109 | 110 | ```C 111 | STRING A[] = {"apple", "banana", "orange", "grapes"}; 112 | FOREACH (STRING *i, A){ 113 | printf("I love %s\n", *i); 114 | } 115 | 116 | /* OUTPUT: 117 | I love apple 118 | I love banana 119 | I love orange 120 | I love grapes */ 121 | ``` 122 | 123 | See also `STRING` in strings section. 124 | 125 | Obviously, for single line statements, `{}` are not required. 126 | 127 | ### Math 128 | 129 | There are a lot of macros for mathematical purposes. 130 | 131 | - PI 132 | - RAD2DEG(x) 133 | - DEG2RAD(x) 134 | 135 | These can be used to convert angles, where PI is a constant. 136 | 137 | ```C 138 | printf("%d ", RAD2DEG(PI) ); 139 | 140 | /* OUTPUT: 141 | 180 */ 142 | ``` 143 | 144 | - ALIGNB(x, align) 145 | - ALIGN(x, align) 146 | - FLOORB(x, align) 147 | - FLOOR(x, align) 148 | - CEILB(x, align) 149 | - CEIL(x, align) 150 | - CLIP(x, min, max) 151 | - UCLIP(x, max) 152 | - LCLIP(x, min) 153 | - MIN(x, y) 154 | - MAX(x, y) 155 | - ABS(x) 156 | - DIFF(a,b) 157 | 158 | Functioning of above Macros are quite obvious. **(TL;D write!)** 159 | 160 | - ISNAN(x) 161 | 162 | For example, ISNAN (0.0/0.0), It Checks if x is NOT A NUMBER. 163 | 164 | - IMPLIES(x, y) 165 | 166 | - SWAP(a, b) 167 | - SORT(a, b) 168 | 169 | These two are interesting. Also if you look at their #defines, they don't have any temporary variable. 170 | 171 | ```C 172 | int x = 10, y = 5, z = 0; 173 | SORT(x,y); /*now x should be smaller one*/ 174 | SWAP(x,z); /*now z and x swaps */ 175 | printf("%d", z); 176 | 177 | /* OUTPUT: 178 | 5 */ 179 | 180 | ``` 181 | 182 | - COMPARE(x, y) 183 | - SIGN(x) 184 | 185 | Returns `1` on positive and `-1` on negative. 186 | 187 | - IS_ODD( num ) 188 | - IS_EVEN( num ) 189 | - IS_BETWEEN(n,L,H) 190 | 191 | For example: 192 | 193 | ```C 194 | int x; 195 | printf("Enter a num: "); 196 | scanf("%d", &x); 197 | if ( IS_EVEN (x) && IS_BETWEEN(x, 0, 20) ){ 198 | printf("working... \n"); 199 | } 200 | 201 | /* OUTPUT: 202 | Enter a num: 12 203 | working...*/ 204 | 205 | ``` 206 | 207 | 208 | ### Bits 209 | 210 | - BIT(x) 211 | - SETBIT(x,p) 212 | - CLEARBIT(x,p) 213 | - GETBIT(x,p) 214 | - TOGGLEBIT(x,p) 215 | 216 | People use constant 1024 many times, now you can get it simply by `BIT(10)`. 217 | 218 | ### Arrays 219 | 220 | - ARRAY_SIZE(a) 221 | - SET(d, n, v) 222 | - ZERO(d, n) 223 | - COLUMNS(S,E) 224 | - IS_ARRAY(a) 225 | 226 | ```C 227 | int arr[] = {1,2,3,4,5,6,7,8,9,10}; 228 | if(IS_ARRAY(arr)) { 229 | SET(arr, ARRAY_SIZE(arr)-4, 10); 230 | ZERO(arr, 3); 231 | } 232 | RANGE(x, 0, 9) printf("%d ", arr[x]); 233 | 234 | /* OUTPUT: 235 | 0 0 0 10 10 10 7 8 9 10 */ 236 | ``` 237 | 238 | ### Strings 239 | 240 | - STRING 241 | 242 | Its translates to char*. 243 | 244 | ```C 245 | STRING x = "hello"; 246 | STRING list[] = {"book", "ball", "bucket"}; 247 | ``` 248 | 249 | - CAT(str1, str2) 250 | 251 | Concatenation of two pure strings. 252 | 253 | ```C 254 | puts ( CAT ("PenPineapple", "ApplePen") ); 255 | 256 | /* OUTPUT: 257 | PenPineappleApplePen */ 258 | ``` 259 | 260 | - STR(s) 261 | 262 | Expands s as a string. 263 | 264 | ```C 265 | puts ( STR (This is a fruit) ); 266 | 267 | /* OUTPUT: 268 | This is a fruit */ 269 | ``` 270 | 271 | ### Tokens 272 | 273 | - PASTE(a,b) 274 | - PRINT_TOKEN(token) 275 | 276 | ```C 277 | a = 10; 278 | b = 20; 279 | ab = 0; 280 | x = PASTE(a,b); 281 | PRINT_TOKEN( x ); 282 | 283 | /* OUTPUT: 284 | x is 0 */ 285 | ``` 286 | 287 | ### Debugging 288 | 289 | - LOG (x, fmt, ...) 290 | - TRY (x, s) 291 | - ASSERT (n) 292 | 293 | ASSERT Macro will require DEBUG to be defined. Also on error, it will return -1 to exit. TRY performs x. Only on error, it shows custom error message. LOG is reverse, it produces message on success of x. 294 | 295 | ```C 296 | #define DEBUG /* To use ASSERT */ 297 | #include "macro.h" 298 | ... 299 | LOG(x=5,"Now square of x is %d", x*x); 300 | TRY(0>10, "We already knew its an error\n"); 301 | ASSERT(1>2); 302 | 303 | /* OUTPUT: 304 | test.c@125: Now square of x is 25 305 | test.c@127: We already knew its an errortest.c@138: `1>2` - Failed | Compilation: Jun 14 2022 10:20:12 306 | ``` 307 | 308 | ### Saturation 309 | 310 | - SATINC(v,L) 311 | - SATDEC(w,L) 312 | 313 | A saturating macro which does v++ and w-- respectively on every call, and does nothing on reaching L limit. 314 | 315 | ```C 316 | a = 0, b = 7; 317 | for(x=0; x<10; x++){ 318 | SATINC(a,7); 319 | SATDEC(b,0); 320 | printf("%d %d, ",a,b); 321 | } 322 | 323 | /* OUTPUT: 324 | 1 6, 2 5, 3 4, 4 3, 5 2, 6 1, 7 0, 7 0, 7 0, 7 0, */ 325 | ``` 326 | 327 | ### Statements 328 | 329 | - STMT(stuff) 330 | 331 | Macros involving multiple statements needs braces which are safer to define with a do_while(0) for single execution. STMT expands statements the same way. 332 | 333 | ```C 334 | STMT (printf("it should be in a macro...\n");); 335 | ``` 336 | 337 | - ONCE ( stmts ) 338 | 339 | This Macro make it sure that the statements within it are performed only once. 340 | 341 | ```C 342 | a = 1; 343 | RANGE(x,0,10) { 344 | /*ONCE(*/ 345 | a++; 346 | /*);*/ 347 | } 348 | printf("%d\n", a); 349 | 350 | /* With ONCE */ 351 | a = 1; 352 | RANGE(x,0,10) { 353 | ONCE( 354 | a++; 355 | ); 356 | } 357 | printf("%d\n", a); 358 | 359 | /* OUTPUT: 360 | 12 361 | 2 */ 362 | ``` 363 | 364 | See also `FOREVER` in Loops section. 365 | 366 | - DEFER 367 | 368 | Run an init and a cleanup statement. The init, cleanup and block statements are all under the same scope. One line statements are fine without braces. 369 | 370 | ``` 371 | /* DEFER */ 372 | DEFER(FILE *f = fopen("file.txt", "w+"), fclose(f)) { 373 | fprintf(f, "I love %s!\n", "coffee"); 374 | } 375 | ``` 376 | 377 | ### Extern C 378 | 379 | - EXTERN_C_START 380 | - EXTERN_C_END 381 | 382 | These macros are for C++ users. To compile a piece of C code in C++ environment, you can use these macros as follows: 383 | 384 | ```C 385 | //somecppfile.cpp 386 | 387 | // CPP 388 | EXTERN_C_START 389 | 390 | /* C */ 391 | 392 | #include 393 | int main(void) 394 | { 395 | int new = 10; 396 | printf("%d", new); 397 | } 398 | 399 | EXTERN_C_END 400 | // CPP 401 | 402 | /* OUTPUT: 403 | 10 */ 404 | ``` 405 | 406 | As 'new' is a C++ keyword, this would never be compiled with a C++ compiler, but its valid in C. So we used those macros to mix C in C++. 407 | 408 | ### Functions shorthands 409 | 410 | - MAIN() 411 | 412 | A shorthand for `int main (int argc, const char **argv)` 413 | 414 | - NOW() 415 | 416 | A shorthand `time(NULL)`. Please do note that `#include ` is required for the time related types. 417 | 418 | ## Contribute 419 | 420 | The source is very clear and the macros available are too common you will find them everywhere. A good Macro is : Portable, safe, involves as less arbitrary variables as possible. Although I am trying my best, there might be some exception errors, please correct if you find any. Also, if I missed some other interesting macros, please contribute to make this collection complete and more usable. 421 | 422 | ### Conventions 423 | 424 | 1. All macros are in UPPERCASE. 425 | 2. In case of any Boolean Macro, the `IS_ prefix` should be used. For example, `IS_EVEN(x)`. And they should return a `1` or `0` value. 426 | 3. Macros for loops and conditionals should not end with braces so that the user can have the option for single line as well as block style. 427 | 4. A helper macro, which are expanded by some other main macro, usually they are not intended to be used directly. So they should be mentioned with their expansion level as prefix. For example, `PASTE(a,b)` expands into `PASTE2(a,b)` which further expands into `a##b`. 428 | 429 | ## Credit 430 | 431 | >The real credits goes to all those great C coders who came up with such creative use of C Macros to extend C. I made this collection in honor of The C language and those unknown programmers. I can only take credit for the efforts I made to collect and bringing it to you. 432 | 433 | ### Contributors ✨ 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | ## License 442 | 443 | Copyright 2017, Shubham Ramdeo. Code released under the [MIT License](https://github.com/ramdeoshubham/macros/blob/master/LICENSE). 444 | 445 | 446 | >#Handpicked C #Macros with ♥ #love ! 447 | 448 | Don't forget to [★`STAR`](https://github.com/ramdeoshubham/macros) if you like it. 449 | -------------------------------------------------------------------------------- /macros.h: -------------------------------------------------------------------------------- 1 | /** 2 | MACROS 3 | macros.h 4 | Purpose: A collection of commonly used Useful C macros. 5 | 6 | @author Shubham Ramdeo 7 | @version 0.2 8 | 9 | Released under MIT LICENSE (see LICENSE.txt) 10 | */ 11 | 12 | #ifndef MACROS_H 13 | #define MACROS_H 14 | 15 | /* Bool */ 16 | 17 | #define TRUE 1 18 | #define FALSE 0 19 | 20 | /* Identifier */ 21 | 22 | #define AND && 23 | #define OR || 24 | #define NOT ! 25 | #define NOTEQUALS != 26 | #define EQUALS == 27 | #define IS = 28 | 29 | /* TYPES */ 30 | 31 | #define INT16 short 32 | #define UINT16 unsigned short 33 | #define INT32 int 34 | #define UINT32 unsigned int 35 | #define INT64 long long 36 | #define UINT64 unsigned long long 37 | 38 | /* Loops */ 39 | 40 | #define FOREVER for(;;) 41 | #define RANGE(i,y,x) for(i=(y);(((x)>=(y))?(i<=(x)):(i>=x));\ 42 | (((x)>=(y))?((i)++):((i)--))) 43 | #define FOREACH(i, A) for(int _keep=1, \ 44 | _count=0,\ 45 | _size=sizeof (A) / sizeof *(A); \ 46 | _keep && _count != _size; \ 47 | _keep = !_keep, _count++) \ 48 | for(i = (A)+_count; _keep; _keep = !_keep) 49 | 50 | /* Maths */ 51 | 52 | #define PI 3.14159265 53 | #define RAD2DEG(x) ((x)/PI*180) 54 | #define DEG2RAD(x) ((x)*PI/180) 55 | #define ALIGNB(x, align) (((x) + ((align) - 1)) & ~((align) - 1)) 56 | #define ALIGN(x, align) ((((x) + ((align) - 1)) / (align)) * (align)) 57 | #define FLOORB(x, align) ((x) & ~((align) - 1)) 58 | #define FLOOR(x, align) (((x) / (align)) * (align)) 59 | #define CEILB(x, align) ALIGNB(x, align) 60 | #define CEIL(x, align) ALIGN(x, align) 61 | #define CLIP(x, min, max) (((x) < (min)) ? (min) : \ 62 | (((x) > (max)) ? (max) : (x))) 63 | #define UCLIP(x, max) (((x) > (max)) ? (max) : (x)) 64 | #define LCLIP(x, min) (((x) < (min)) ? (min) : (x)) 65 | #define MIN(x, y) (((x) < (y)) ? (x) : (y)) 66 | #define MAX(x, y) (((x) > (y)) ? (x) : (y)) 67 | #define ABS(x) (((x) < 0) ? -(x) : (x)) 68 | #define DIFF(a,b) ABS((a)-(b)) 69 | #define IS_NAN(x) ((x) != (x)) 70 | #define IMPLIES(x, y) (!(x) || (y)) 71 | #define SWAP(a, b) do { a ^= b; b ^= a; a ^= b; } while ( 0 ) 72 | #define SORT(a, b) do { if ((a) > (b)) SWAP((a), (b)); } while (0) 73 | #define COMPARE(x, y) (((x) > (y)) - ((x) < (y))) 74 | #define SIGN(x) COMPARE(x, 0) 75 | #define IS_ODD( num ) ((num) & 1) 76 | #define IS_EVEN( num ) (!IS_ODD( (num) )) 77 | #define IS_BETWEEN(n,L,H) ((unsigned char)((n) >= (L) && (n) <= (H))) 78 | 79 | /* BITS */ 80 | 81 | #define BIT(x) (1<<(x)) 82 | #define SETBIT(x,p) ((x)|(1<<(p))) 83 | #define CLEARBIT(x,p) ((x)&(~(1<<(p)))) 84 | #define GETBIT(x,p) (((x)>>(p))&1) 85 | #define TOGGLEBIT(x,p) ((x)^(1<<(p))) 86 | 87 | /* ARRAYS */ 88 | 89 | #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 90 | #define SET(d, n, v) do{ size_t i_, n_; \ 91 | for ( n_ = (n), i_ = 0; n_ > 0; --n_, ++i_) \ 92 | (d)[i_] = (v); } while(0) 93 | #define ZERO(d, n) SET(d, n, 0) 94 | #define COLUMNS(S,E) ( (E) - (S) + 1 ) 95 | #define IS_ARRAY(a) ((void *)&a == (void *)a) 96 | 97 | /* STRINGS */ 98 | 99 | #define STRING char* 100 | #define STR2(s) #s 101 | #define STR(s) STR2(s) 102 | #define CAT(str1,str2) (str1 "" str2) 103 | 104 | /* TOKENS */ 105 | 106 | #define PASTE2(a,b) a##b 107 | #define PASTE(a,b) PASTE2(a,b) 108 | #define PRINT_TOKEN(token) printf(#token " is %d", token) 109 | 110 | /* DEBUGGING */ 111 | 112 | #define LOG(x, fmt, ...) if(x){printf("%s@%d: " fmt "\n",\ 113 | __FILE__, __LINE__,__VA_ARGS__);} 114 | #define TRY(x,s) if(!(x)){printf("%s@%d: %s",__FILE__, __LINE__,s);} 115 | /*you have to #define DEBUG to enable ASSERT*/ 116 | #ifndef DEBUG 117 | #define ASSERT(n) 118 | #else 119 | #define ASSERT(n) if(!(n)){\ 120 | printf(__FILE__ "@%d: `" #n "` - Failed | Compilation: " __DATE__ " " __TIME__ "\n", __LINE__);\ 121 | return(-1);} 122 | #endif 123 | 124 | /* DEFER, useful to init and clean a block of scoped code */ 125 | /* Please see https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2895.htm for a more in depth guide explaining non-standard cleanup functions */ 126 | 127 | #define DEFER2(head, tail, i) for(int i=(head,0);!i;tail,i++) 128 | #define DEFER(head, tail) DEFER2(head, tail, __deferVar__##__COUNTER__) 129 | 130 | /* STMT, useful for creating multiple statements macros */ 131 | 132 | #define STMT( stuff ) do { stuff } while (0) 133 | 134 | /* Saturating ++ and -- */ 135 | 136 | #define SATINC(w,L) (w = (((w) == (L)) ? (w) : ((w) + 1)) ) 137 | #define SATDEC(w,L) (w = (((w) == (L)) ? (w) : ((w) - 1)) ) 138 | 139 | /* ONCE */ 140 | #define ONCE2(stmts, i) {static int i = 1;\ 141 | if(i){stmts\ 142 | i = 0;}} 143 | #define ONCE(stmts) ONCE2(stmts, __onceVar__##__COUNTER__) 144 | 145 | /* C in C++ Environment */ 146 | 147 | #ifdef __cplusplus 148 | # define EXTERN_C_START extern "C" { 149 | # define EXTERN_C_END } 150 | #else 151 | # define EXTERN_C_START 152 | # define EXTERN_C_END 153 | #endif 154 | 155 | /* User ID */ 156 | #define EFFECTIVE_USER_ID geteuid() 157 | #define USER_ID getuid() 158 | 159 | /* Exit program */ 160 | #define DIE exit(0) 161 | 162 | /* other contributions from Github users */ 163 | 164 | #define CONSTRAIN(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) 165 | /* https://github.com/ramdeoshubham/macros/issues/4 */ 166 | 167 | 168 | /* Functions shorthands useful for code tidiness */ 169 | 170 | #define MAIN() int main (int argc, const char **argv) 171 | #define NOW time(NULL) 172 | 173 | #endif /* MACROS_H */ 174 | -------------------------------------------------------------------------------- /test.c: -------------------------------------------------------------------------------- 1 | /** 2 | MACROS 3 | test.c 4 | Purpose: This file demostrates examples usage of macros.h. 5 | 6 | @author Shubham Ramdeo 7 | @version 0.2 8 | 9 | Released under MIT LICENSE (see LICENSE.txt) 10 | */ 11 | 12 | /* I believe we need a better example file...! */ 13 | /* MORE Comming soon... */ 14 | 15 | 16 | #include 17 | #include 18 | 19 | /* For ASSERT macro to work */ 20 | #define DEBUG 21 | 22 | #include "macros.h" 23 | 24 | /* If you compile this file with a C++ compiler, this will make it work*/ 25 | EXTERN_C_START 26 | 27 | MAIN () { 28 | 29 | int x = 0, a, b, ab; 30 | 31 | /* Boolean */ 32 | 33 | while (TRUE) { 34 | if( (x > 5) == FALSE ) break; 35 | x++; printf("hi "); 36 | } 37 | 38 | /* Operators */ 39 | 40 | x = 5; 41 | if( x EQUALS 0 OR x > 10 AND x NOTEQUALS 15) 42 | { 43 | x IS 1; 44 | } 45 | else if ( NOT (x > 0) ) { 46 | x IS 0; 47 | } 48 | else x IS 100; 49 | printf("\n%d\n",x); 50 | 51 | /* Loops */ 52 | 53 | FOREVER{ 54 | if( x > 5 ) break; 55 | x++;printf("hi "); 56 | } 57 | 58 | RANGE(x, 10, 20){ 59 | printf("%d ", x); 60 | } 61 | 62 | RANGE (x, 5, -5){ 63 | printf("%d ", x); 64 | } 65 | 66 | STRING A[] = {"apple", "banana", "orange", "grapes"}; 67 | FOREACH (STRING *si, A){ 68 | printf("I love %s\n", *si); 69 | } 70 | 71 | /* ARRAYS */ 72 | int arr[] = {1,2,3,4,5,6,7,8,9,10}; 73 | if(IS_ARRAY(arr)) { 74 | SET(arr, ARRAY_SIZE(arr)-4, 10); 75 | ZERO(arr, 3); 76 | } 77 | RANGE(x, 0, 9) printf("%d\n", arr[x]); 78 | 79 | /* STRINGS */ 80 | STRING sss = "hello"; 81 | STRING list[] = {"book", "ball", "bucket"}; 82 | 83 | puts ( CAT ("PenPineapple", "ApplePen") ); 84 | puts ( STR (This is a fruit) ); 85 | 86 | /* TOKEN */ 87 | a = 10; 88 | b = 20; 89 | ab = 0; 90 | x = PASTE(a,b); 91 | PRINT_TOKEN( x ); 92 | 93 | /* STMT */ 94 | STMT (printf("it should be in a macro...\n");); 95 | 96 | /*Saturating -- and ++ */ 97 | a = 0, b = 7; 98 | for(x=0; x<10; x++){ 99 | SATINC(a,7); 100 | SATDEC(b,0); 101 | printf("%d %d, ",a,b); 102 | } 103 | 104 | /* Once */ 105 | 106 | /* without ONCE */ 107 | a = 1; 108 | RANGE(x,0,10) { 109 | /*ONCE(*/ 110 | a++; 111 | /*);*/ 112 | } 113 | printf(" %d ", a); 114 | 115 | /* With ONCE */ 116 | a = 1; 117 | RANGE(x,0,10) { 118 | ONCE( 119 | a++; 120 | ); 121 | } 122 | printf(" %d ", a); 123 | 124 | 125 | LOG(x=5,"Now square of x is %d", x*x); 126 | 127 | TRY(0>10, "We already knew its an error\n"); 128 | 129 | /* DEFER */ 130 | DEFER(printf("Before DEFER. Already inside. ["), printf("] After DEFER. Still inside.\n")) { 131 | printf("] Inside DEFER. ["); 132 | } 133 | 134 | /* NOW */ 135 | printf("UNIX epoch: %lu\n", NOW); 136 | 137 | /* ASSERT will return -1 therefore its intentionally placed at the end. */ 138 | ASSERT(1>2); 139 | 140 | return 0; 141 | } 142 | 143 | EXTERN_C_END 144 | --------------------------------------------------------------------------------