basic-shell / tokenize_helper.c
tokenize_helper.c
Raw
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "tokenize.h"

/* Is the given character a special char?
 * Returns true if it is one of our specially recognized characters,
 * false otherwise*/
bool special(char itm) {
	char specials[]  = {'(', ')', '<', '>', ';', '|'};  
        for (int i = 0; i < ((sizeof specials) / (sizeof specials[0])); i++) {
                if (strncmp(&itm, &specials[i], 1) == 0) {
                        return true;
                }
        }
        return false;
}

/* Add the given item to the tokens vector*/
void place_item(char* curr, vect_t* tokens) {
	if (strlen(curr) > 0) {
		vect_add(tokens, curr);
	}
}

/* Finds the remaining portion of words to add
 * and calls add_word to add it to the vector we are building, 
 * using the given index as a reference point.
 * Errors if it cannot find a matching end quote to the input.
 * Returns the next index to continue processing.*/
int place_remaining_quote(char* items, vect_t* tokens, int start) {
        // this array will hold the rest of the words 
	// we pass into add_word to add
	char elems[MAX_SIZE] = "\0";
	int i = start;
        while (strncmp(&items[i], "\"", 1) != 0) {
		// if there is no ending quote (i.e. malformation)
		// exit with 1
		if (strncmp(&items[i], "\0", 1) == 0) {
			exit(1);
		}
		// copy the words from given input into smaller
		// array we can pass off to add into vector
                strncat(elems, &items[i], sizeof(items[i]));
		i++;
        }
	place_item(elems, tokens);
        return i+1;
}



/* Creates and returns a vector of the tokens 
 * in the given input.*/
vect_t* create_tokens(char* items) {

	// instantiate variables to hold token
	vect_t *tokens = vect_new(); 
	// current word 
	char current[MAX_SIZE] = "\0"; 

	int i = 0; 
	// iterate through each item and add it to the 
	// vector we are creating
	while (items[i] != '\0' && i < MAX_SIZE) {
		// quote case
	  	if (strncmp(&items[i], "\"", 1) == 0) {
			place_item(current, tokens);
			memset(current, '\0', MAX_SIZE);
			i = place_remaining_quote(items, tokens, i+1);
		}
		// whitespace case
		else if (strncmp(&items[i], " ", 1) == 0) {
			// add the current word we built
			// (since whitespace indicates its done)
                        place_item(current, tokens);
			memset(current, '\0', MAX_SIZE);
			i++;
		}
		// tab case
		else if ((i + 1) < MAX_SIZE
			       	&& items[i + 1] != '\0'
				&& (strncmp(&items[i], "\t", 2) == 0)) {
                        	place_item(current, tokens);
                        	memset(current, '\0', MAX_SIZE);
                        	i += 2;
		}
	        // special characters case	
		else if (special(items[i])) {
			// first, add whatever we already processed
			place_item(current, tokens);
			memset(current, '\0', MAX_SIZE);
			// now, add the special symbol itself
			strncat(current, &items[i], sizeof(items[i]));
			place_item(current, tokens);
			memset(current, '\0', MAX_SIZE);
			i++;
		}
		// otherwise, simply make new vector with entry
		else {
			strncat(current, &items[i], sizeof(items[i]));
			i++;
		}
	}

	// once here, current should hold the word to add into our vector
	place_item(current, tokens);
	return tokens;
}