Showing posts with label Stack. Show all posts
Showing posts with label Stack. Show all posts

Return the number of tokens given a command

C Program Return the number of tokens given a command


  1. /* in setup_stack()... */  
  2.  
  3.   int i = 0;
  4.   int argc = get_argc(file_name);
  5.   char *token, *save_ptr;
  6.   char **argv = malloc((argc + 1) * sizeof(char *));
  7.   size_t token_size;
  8.  
  9.   //generate argv and push args onto stack

  10.   for (token = strtok_r((char *)file_name, " ", &save_ptr); token != NULL; token = strtok_r(NULL, " ", &save_ptr)) {
  11.     token_size = strlen(token) + 1;
  12.     *esp = *esp - token_size;
  13.     argv[i] = *esp;
  14.     i++;
  15.     memcpy(*esp, token, token_size);
  16.   } argv[argc] = 0;
  17.  
  18.   //perform alignment

  19.   size_t alignment = (size_t) *esp % 4;
  20.   if (alignment) {
  21.     *esp = *esp - alignment;
  22.     memcpy(*esp, &argv[argc], alignment);
  23.   }
  24.  
  25.   //push argv pointers

  26.   for (= argc; i >= 0; i--) {
  27.     *esp = *esp - sizeof(char *);
  28.     memcpy(*esp, &argv[i], sizeof(char *));
  29.   }
  30.  
  31.   //push pointer to argv

  32.   char *ptr = *esp;
  33.   *esp = *esp - sizeof(char **);
  34.   memcpy(*esp, &ptr, sizeof(char **));
  35.  
  36.   //push argc
  37.   *esp = *esp - sizeof(int);
  38.   memcpy(*esp, &argc, sizeof(int));
  39.  
  40.  //push dummy return address

  41.   *esp = *esp - sizeof(void *);
  42.   memcpy(*esp, &argv[argc], sizeof(void *));
  43.  
  44.   free(argv);
  45.   return success;
  46. }
  47.  
  48. /* Return the number of tokens given a command 'file_name.' */

  49. int get_argc(const char* file_name) {
  50.     int argc = 0;
  51.     char *buffer, *token, *save_ptr;
  52.     buffer = malloc(sizeof(file_name));
  53.     strlcpy(buffer, file_name, sizeof(file_name));
  54.     for (token = strtok_r((char *)buffer, " ", &save_ptr); token != NULL; token = strtok_r(NULL, " ", &save_ptr)) {
  55.         argc++;
  56.     }
  57.     free(buffer);
  58.     return argc;
  59. }

Generic stack in C Program

How to Declares a stack structure and functions generically using a C macro in C Programming Language ?


Solution:


#ifndef __ETS_STACK__
#define __ETS_STACK__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dbg.h>	// Contains function exitWithMessage

/*

DESCRIPTION:
	Declares a stack structure and functions generically using a C macro.


NORMAL TYPE USAGE:	(int, char, float, ...)
	DEFINE_STACK(float) // Put this in the correct scope (global probably).

	Stack_float stack1;
	Stack_float_init( &stack1 , 10 );	// Initialize with maximum capacity being 10.

	Stack_float_push( &stack1, (float)5);  // Pushes the float value into stack1
	float a = Stack_float_pop( &stack1 );

	printf("%f", a); // Will print 5.0000...

	Stack_float_free( &stack1 );


POINTER TYPE USAGE:	(char*, string, ...)
	typedef char* string
	DEFINE_STACK(string)	// TYPE can't contain a '*' token, so typedef to bypass restriction.

	Stack_string this_is_another_stack;
	Stack_string_init( &this_is_another_stack, 1 ); // Initialize with maximum capacity being 1.

	string test = (string) malloc(5 * sizeof(char)); // If not on heap then BAD things can happen, (but whatever i don't judge).
	test[0] = 'h';					 // (Just don't free a variable on the stack)
	test[1] = 'e';
	test[2] = 'y';
	test[3] = '\0';

	Stack_string_push( &this_is_another_stack, test);
	string temp = Stack_string_pop( &this_is_another_stack);

	printf("%s", temp);		// Prints "hey"

	free(temp);		// REMEMBER to free elements after poping to prevent memory leaks.

	Stack_string_free( &this_is_another_stack );


*/

#define DEFINE_STACK(TYPE) \
	\
typedef struct{	\
	TYPE *array; \
	int top; \
	int capacity; \
}Stack_##TYPE##; \
 \
void Stack_##TYPE##_init(Stack_##TYPE *stack, int capacity){ \
	stack->top=-1; \
	stack->capacity = capacity; \
	stack->array = ( TYPE *)calloc(stack->capacity, sizeof( TYPE )); \
} \
 \
void Stack_##TYPE##_push(Stack_##TYPE *stack, TYPE data){ \
	if(stack->top < stack->capacity)	stack->array[++(stack->top)] = data; \
		else	exitWithMessage("ERROR: too many items for stack."); \
} \
 \
TYPE Stack_##TYPE##_pop(Stack_##TYPE *stack){ \
	if(stack->top >= 0)	{	\
		TYPE var = stack->array[stack->top--]; \
		stack->array[stack->top+1] = 0;	\
		return var; \
		} else	exitWithMessage("ERROR: can't pop, no items in stack."); \
} \
	\
void Stack_##TYPE##_free(Stack_##TYPE *stack){	\
	free(stack->array);	\
}	\


#endif // !__ETS_STACK__