ltkx

GUI toolkit for X11 (WIP)
git clone git://lumidify.org/ltkx.git
Log | Files | Refs | README | LICENSE

stack.h (3900B)


      1 /*
      2  * This file is part of the Lumidify ToolKit (LTK)
      3  * Copyright (c) 2020 lumidify <nobody@lumidify.org>
      4  * Based on the stack from libraqm.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a copy
      7  * of this software and associated documentation files (the "Software"), to deal
      8  * in the Software without restriction, including without limitation the rights
      9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     10  * copies of the Software, and to permit persons to whom the Software is
     11  * furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in all
     14  * copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     22  * SOFTWARE.
     23  */
     24 
     25 #ifndef _LTK_STACK_H_
     26 #define _LTK_STACK_H_
     27 
     28 /* This is a "macro'd" and modified version of raqm's stack */
     29 
     30 #define LTK_STACK_INIT_DECL(name, type1, type2, data1, data2)			\
     31 struct ltk_stack_##name {							\
     32   size_t capacity;								\
     33   size_t size;									\
     34   type1 *data1;									\
     35   type2 *data2;									\
     36 };										\
     37 										\
     38 int ltk_stack_pop_##name(struct ltk_stack_##name *stack);			\
     39 type1 ltk_stack_top1_##name(struct ltk_stack_##name *stack, type1 def);		\
     40 void ltk_stack_destroy_##name(struct ltk_stack_##name *stack);			\
     41 int ltk_stack_push_##name(							\
     42     struct ltk_stack_##name *stack, type1 data1, type2 data2);			\
     43 type2 ltk_stack_top2_##name(struct ltk_stack_##name *stack, type2 def);		\
     44 struct ltk_stack_##name *ltk_stack_create_##name(size_t max);
     45 
     46 #define LTK_STACK_INIT_IMPL(name, type1, type2, data1, data2)			\
     47 struct ltk_stack_##name *							\
     48 ltk_stack_create_##name(size_t max) {						\
     49 	struct ltk_stack_##name *stack;						\
     50 	stack = malloc(sizeof(struct ltk_stack_##name));			\
     51 	if (!stack) goto error;							\
     52 										\
     53 	stack->data1 = malloc(sizeof(type1) * max);				\
     54 	if (!stack->data1) goto error;						\
     55 	stack->data2 = malloc(sizeof(type2) * max);				\
     56 	if (!stack->data2) goto error;						\
     57 										\
     58 	stack->size = 0;							\
     59 	stack->capacity = max;							\
     60 										\
     61 	return stack;								\
     62 error:										\
     63 	(void)fprintf(stderr, "Cannot allocate memory for stack\n");		\
     64 	exit(1);								\
     65 }										\
     66 										\
     67 int										\
     68 ltk_stack_pop_##name(struct ltk_stack_##name *stack) {				\
     69 	if (!stack->size)							\
     70 		return 0;							\
     71 										\
     72   stack->size--;								\
     73 										\
     74   return 1;									\
     75 }										\
     76 										\
     77 type1										\
     78 ltk_stack_top1_##name(struct ltk_stack_##name *stack, type1 def) {		\
     79 	if (!stack->size)							\
     80 		return def;							\
     81 										\
     82 	return stack->data1[stack->size];					\
     83 }										\
     84 										\
     85 type2										\
     86 ltk_stack_top2_##name(struct ltk_stack_##name *stack, type2 def) {		\
     87 	if (!stack->size)							\
     88 		return def;							\
     89 										\
     90 	return stack->data2[stack->size];					\
     91 }										\
     92 										\
     93 int										\
     94 ltk_stack_push_##name(struct ltk_stack_##name *stack,				\
     95     type1 data1, type2 data2) {							\
     96 	if (stack->size == stack->capacity)					\
     97 		return 0;							\
     98 										\
     99 	stack->size++;								\
    100 	stack->data1[stack->size] = data1;					\
    101 	stack->data2[stack->size] = data2;					\
    102 										\
    103 	return 1;								\
    104 }										\
    105 										\
    106 void										\
    107 ltk_stack_destroy_##name(struct ltk_stack_##name *stack) {			\
    108   free(stack->data1);								\
    109   free(stack->data2);								\
    110   free(stack);									\
    111 }
    112 
    113 #endif /* _LTK_STACK_H_ */