/**
*  Mark a single dependency on the list_node LIST by adding a pointer (to char * WORD)
*  to LIST->write_list (if WRITE) or LIST->read_list (if not WRITE).
**/
void
mark_read_write(list_node *list, char *word, bool write)
{
  // ignore options
  char first = word[0];
  if (first == '-') {
    return;
  }

  if (write) {
    // write
    list->write_size++;
    if (list->write_list) {
      list->write_list = (char **)checked_realloc(list->write_list, list->write_size*sizeof(char*));
    } else {
      list->write_list = (char **)checked_malloc(list->write_size*sizeof(char*));
    }
    list->write_list[list->write_size-1] = word;
  } else {
    // read
    list->read_size++;
    if (list->read_list) {
      list->read_list = (char **)checked_realloc(list->read_list, list->read_size*sizeof(char*));
    } else {
      list->read_list = (char **)checked_malloc(list->read_size*sizeof(char*));
    }
    list->read_list[list->read_size-1] = word;
  }
}
Exemplo n.º 2
0
void
get_files(command_t cmd, char ***ip_array, char ***op_array, int *input_size, int *output_size)
{
	if(cmd == NULL) {
		return;
	}
	
	switch(cmd->type) {
		case AND_COMMAND:
		case SEQUENCE_COMMAND:
		case OR_COMMAND:
		case PIPE_COMMAND:
			get_files(cmd->u.command[0],ip_array,op_array,input_size,output_size);
			get_files(cmd->u.command[1],ip_array,op_array,input_size,output_size);
			break;
		case SUBSHELL_COMMAND:
			if(cmd->input != NULL) {
				*ip_array = (char**)checked_realloc(*ip_array,(*input_size+1)*sizeof(char*));
				copy_file(*ip_array,cmd->input,input_size);
			}
			if(cmd->output != NULL) {
				*op_array = (char**)checked_realloc(*op_array,(*output_size+1)*sizeof(char*));
				copy_file(*op_array,cmd->output,output_size);
			}
			get_files(cmd->u.subshell_command,ip_array,op_array,input_size,output_size);
			break;
		case SIMPLE_COMMAND:
			if(cmd->input != NULL) {
				*ip_array = (char**)checked_realloc(*ip_array,(*input_size+1)*sizeof(char*));
				copy_file(*ip_array,cmd->input,input_size);
			}
			if(cmd->output != NULL) {
				*op_array = (char**)checked_realloc(*op_array,(*output_size+1)*sizeof(char*));
				copy_file(*op_array,cmd->output,output_size);
			}
			char **w = cmd->u.word;
			
			/*start at the second word, first word is the command */
			w++;
			while(*w) {
				*ip_array = (char**)checked_realloc(*ip_array,(*input_size+1)*sizeof(char*));
				copy_file(*ip_array,*w,input_size);
				w++;
			}
			break;
		default:
			return;
	}
	return;
}
Exemplo n.º 3
0
void
_bdd_mgr_double_capacity (bdd_mgr_t *mgr)
{
    unsigned old_capacity = mgr->capacity;
    fprintf (stderr, "!!! begin double\n");
    mgr->capacity *= 2;
    mgr->nodes = (node_t *)
        checked_realloc (mgr->nodes, mgr->capacity * sizeof (node_t));
    _initialize_nodes (mgr->nodes, old_capacity, mgr->capacity);
    mgr->nodes_hash = (unsigned *)
        checked_realloc (mgr->nodes_hash,
                         _bdd_mgr_num_hash_buckets (mgr) * sizeof (unsigned));
    _bdd_mgr_rehash (mgr);
    fprintf (stderr, "!!! end double\n");
}
Exemplo n.º 4
0
command_t get_simple_command(command_stream_t buff)
{
  int numofchar = 0;
  int word_size = 20;
  int current_line;
  int i = 0;
  command_t s = checked_malloc(sizeof(struct command));
  s->u.word = checked_malloc(sizeof(char*) * word_size);

  buff = get_token(buff);
  if(buff->current_token != WORD_T)
      error (1, 0, "Line %d: syntax error near unexpected token %s, it needs to be a WORD"
              , buff->linenum, buff->next_string);

  s->u.word[i] = checked_malloc(sizeof(char*) * strlen(buff->current_string));
  strcpy(s->u.word[i++], buff->current_string);

  while(buff->next_token == WORD_T && (buff = get_token(buff)))
  {
    s->u.word[i] = checked_malloc(sizeof(char*) * strlen(buff->current_string));
    strcpy(s->u.word[i++], buff->current_string);

    if(i >= word_size)
    {
      word_size += 20;
      s->u.word = checked_realloc(s->u.word, sizeof(char*)* word_size);
    }
  }
  s->u.word[i] = '\0';
  s->type = SIMPLE_COMMAND;
  s->canfork = 1;
  return s;
}
Exemplo n.º 5
0
// increase array size for dep node output files
void grow_out_ptr(dep_node_t dn)               
{
        dep_node_out_array_size += DEP_NODE_IO_ARRAY_GROW;
        char **temp = checked_realloc(dn->out, dep_node_out_array_size * sizeof(char**));         
        if (temp == NULL)
                error(1, 0, "Error with memory reallocation\n");
        dn->out = temp;
}
Exemplo n.º 6
0
void *
checked_grow_alloc (void *ptr, size_t *size)
{
  size_t max = -1;
  if (*size == max)
    memory_exhausted (0);
  *size = *size < max / 2 ? 2 * *size : max;
  return checked_realloc (ptr, *size);
}
/**
*  Check for dependencies on a list_node LIST by checking list_nodes which have already
*  been checked and processed. Will compare LIST.read_list and LIST.write_list to the read
*  and write lists of all list_nodes attached to global variable depend_head (which have already
*  been processed).
**/
void
check_dependencies(list_node *list)
{
  list_node *others = depend_head;
  while (others)
  {
    // if others is a dependency of list
    bool dependency = false;

    int other_read_idx = 0;
    int other_write_idx = 0;
    int list_read_idx = 0;
    int list_write_idx = 0;

    // check list's WL against other RLs
    for (other_read_idx = 0; other_read_idx < others->read_size && !dependency; other_read_idx++) {
      for (list_write_idx = 0; list_write_idx < list->write_size; list_write_idx++) {
        if (strcmp(others->read_list[other_read_idx], list->write_list[list_write_idx]) == 0) {
          dependency = true;
          break;
        }
      }
    }

    // check list's RL & WL against other WLs
    for (other_write_idx = 0; other_write_idx < others->write_size && !dependency; other_write_idx++) {
      // check list's RL
      for (list_read_idx = 0; list_read_idx < list->read_size; list_read_idx++) {
        if (strcmp(others->write_list[other_write_idx], list->read_list[list_read_idx]) == 0) {
          dependency = true;
          break;
        }
      }
      // check list's WL
      for (list_write_idx = 0; list_write_idx < list->write_size; list_write_idx++) {
        if (strcmp(others->write_list[other_write_idx], list->write_list[list_write_idx]) == 0) {
          dependency = true;
          break;
        }
      }
    }

    // add others as a dependency on list
    if (dependency) {
      graph_node *node = list->node;
      node->before_size++;
      if (node->before) {
        node->before = (graph_node **)checked_realloc(node->before, node->before_size*sizeof(graph_node*));
      } else {
        node->before = (graph_node **)checked_malloc(node->before_size*sizeof(graph_node*));
      }
      node->before[node->before_size-1] = others->node;
    }
    
    others = others->next;
  }
}
Exemplo n.º 8
0
static void
vector_resize(vector* vec)
{
	if (vec->length == vec->max_length) {
		vec->array = checked_realloc(vec->array, vec->max_length *
		                                         vec->element_size *2);
		vec->max_length *= 2;
	}
}
Exemplo n.º 9
0
void
append_arvore_vec(arvore_vec* v, arvore a)
{
  if (v->size == v->capacity)
  {
    v->array = (arvore*) checked_realloc(v->array,
        sizeof(arvore) * (v->capacity *= 2));
  }
  v->array[v->size++] = a;
}
Exemplo n.º 10
0
void add_char(char** list, int curr, char c)
{
  /* This function adds a character to a current complete command"*/
  
  char* str = list[curr];
  char* tmp = NULL;
  int length = 0;
  if(str == NULL)
  {
    tmp = (char*)checked_realloc(str,sizeof(char)*2);
    tmp[0] = c;
    tmp[1] = '\0';
    list[curr] = tmp;
    return;
  }
  length = strlen(str);
  tmp = (char*)checked_realloc(str,sizeof(char)*(2+length));
  tmp[length] = c;
  tmp[length+1] = '\0';
  list[curr] = tmp;
  return;
}
Exemplo n.º 11
0
VOID reallocate_writeArray_stride(){

	ADDRINT* ptr;

	numWrite *= 2;

	ptr = (ADDRINT*) checked_realloc(instrWrite, numWrite * sizeof(ADDRINT));
	/*if (ptr == (ADDRINT*) NULL) {
		cerr << "Not enough memory (in reallocate_writeArray_stride)" << endl;
		exit(1);
	}*/
	instrWrite = ptr;
}
Exemplo n.º 12
0
//auxiliary function for make_command
int getNextWord(int start, char *token, char **word){
	int bufferSize = 50;
	int i;
	(*word)[0] = '\0';
	for(i = 0; !isEndOfWord(token[start]); i++){
		if(i > bufferSize){
			bufferSize += 10;
			*word = checked_realloc(word, bufferSize);
		}
		(*word)[i] = token[start];
		start++;
		//test 4
		if((*word)[i] == '>' || (*word)[i] == '<'){
			break;
		}
	}
	return start;
}
Exemplo n.º 13
0
  char* makeInputStream(int (*get_next_byte) (void *), void *get_next_byte_argument)
  {
    int inputStreamSize = 100;
    int byteCount = 0;
    int c;
    char *inputStream = (char*)checked_malloc(inputStreamSize*sizeof(char));

    while ((c = get_next_byte(get_next_byte_argument)) != EOF) {
      inputStream[byteCount] = c;
      byteCount++;

      if (byteCount == inputStreamSize) {
        inputStreamSize += 100;
        inputStream = checked_realloc(inputStream, inputStreamSize*sizeof(char));
      }
    }
    inputStream[byteCount] = EOF;
    byteCount++;

    return inputStream;
  }
Exemplo n.º 14
0
//auxiliary function purely to grab input/output files
int getInputOutput(int start, char *token, char**word){
	while(isWhiteSpace(token[start])){
		start++;
	}
	if(isOperator(token[start]) || token[start] == '\0'){
        	fprintf(stderr, "%d: Incorrect Syntax1 \n", line_number);
        	exit(1);
	}
	int bufferSize = 50;
	int i = 0;
	while(!isWhiteSpace(token[start]) && token[start]!='\0'){
		 if(i > bufferSize){
            bufferSize += 50;
            *word = checked_realloc(word, bufferSize);
        }
        (*word)[i] = token[start];
			start++;
			i++;
	}
	(*word)[i] = '\0';
	return start;
}
Exemplo n.º 15
0
void
process_file_list_file(char *filename)
{
    FILE *fp;
    char *line;

    fp = fopen(filename, "r");
    if (fp == NULL) {
        fprintf(stderr, "%s: error opening file `%s': %s\n",
            MR_progname, filename, strerror(errno));
        num_errors++;
        return;
    }
    /* initialize the files structure, if required */
    if (files == NULL) {
        num_files = 0;
        size_of_files = NUMFILES;
        files = (char **) checked_malloc(sizeof(char *) * NUMFILES);
    }

    while ((line = read_line(filename, fp, MAXFILENAME)) != NULL) {
        /* Ignore blank lines */
        if (line[0] != '\0') {
            if (num_files >= size_of_files) {
                size_of_files *= FACTOR;
                files = (char **)
                    checked_realloc(files, size_of_files * sizeof(char *));

                if (files == NULL) {
                    fprintf(stderr, "%s: unable to realloc\n", MR_progname);
                    exit(EXIT_FAILURE);
                }
            }

            files[num_files] = line;
            num_files++;
        }
    }
}
Exemplo n.º 16
0
// create dependency list for time traveling
void setup_new_dep_node(command_t c)
{
        dep_node_in_array_size = DEP_NODE_IO_ARRAY_GROW; // reset IO memory allocations
        dep_node_out_array_size = DEP_NODE_IO_ARRAY_GROW;
        if(numOfDepNodes == 0) // haven't created Dependency Node Tree yet
        {        
            dep_access = checked_malloc(dep_node_array_size * sizeof(dep_node_t));
            if (dep_access == NULL)
                error(1, 0, "Error with memory allocation\n");
        }
        if(numOfDepNodes == dep_node_array_size) // need to grow array for more dep nodes
        {
            dep_node_array_size += DEP_NODE_ARRAY_GROW;
            dep_node_t *temp = checked_realloc(dep_access, dep_node_array_size * sizeof(dep_node_t));
            if (temp == NULL)
                error(1, 0, "Error with memory reallocation\n");
            dep_access = temp;
        }
        dep_access[numOfDepNodes] = checked_malloc(sizeof(struct dep_node));
        if (dep_access[numOfDepNodes] == NULL)
            error(1, 0, "Error with memory allocation\n");
        init_dep_node(c, dep_access[numOfDepNodes]); // initialize dep node 
}
Exemplo n.º 17
0
command_stream_t
make_command_stream(int (*get_next_byte) (void *),
                    void *get_next_byte_argument)
{

    //building the stream string
    int lineNum = 1;

    ////printf("Step 1: Building the buffer string.\n");
    char currChar;
    char* buffer = (char*) checked_malloc(sizeof(char));
    int bufferSize = 0;
    while((currChar = get_next_byte(get_next_byte_argument)) != EOF)
    {
        if(currChar == '\n')
        {
            lineNum++;
        }
        if(!isCharValid(currChar))
        {
            error(1,0,"%d: Syntax error (Illegal character %c found.) \n", lineNum, currChar);
        }
        else if (currChar == '#')
        {
            //while(currChar != '\n' && currChar != EOF)
            while((currChar = get_next_byte(get_next_byte_argument)) != EOF && currChar != '\n')
            {
            }
            if(feof(get_next_byte_argument))
            {
                error(1,0,"%d: Syntax error (Comments need to be terminated with new line)\n", lineNum);
            }
            else
            {
                lineNum++;
            }
        }
        buffer[bufferSize] = currChar;
        bufferSize++;
        buffer = (char*)checked_realloc(buffer, bufferSize+1);
    }
    buffer[bufferSize] = '\0';
    ////printf("Step 1: Buffer Built \n%s\n Strlen(buffer) = %d, bufferSize = %d\n", buffer, strlen(buffer), bufferSize);


    ////printf("Step 2: Clean up iteration started.\n");
    lineNum = 1;
    int prev = -1;
    int n; //next nonwhite space index
    int curr = nextIndex(buffer, bufferSize, -1);
    int next = nextIndex(buffer, bufferSize, curr);
    while (curr < bufferSize)
    {
        ////printf("Step 2: prev = %d, curr = %d, next = %d.\n", prev, curr, next);
        switch (buffer[curr])
        {
        case ';':
            n = nextNonwhitespace(buffer, bufferSize, curr);
            if ((prev==-1) || (n == bufferSize)
                    || !(isWordChar(buffer[prev])||buffer[prev] == ')')  //(;) );(
                    || !(isWordChar(buffer[n])||buffer[n] == '('))
            {
                error(1,0,"%d: Syntax error (Incomplete operators %c found)\n", lineNum, buffer[curr]);
            }
            break;
        case '>':
        case '<':
            //if ((prev==-1) || (nextNonwhitespace(buffer, bufferSize, curr) == bufferSize)
            //  ||(isOperator(buffer[prev])) || (isOperator(buffer[next])))
            if ((prev==-1) || (nextNonwhitespace(buffer, bufferSize, curr) == bufferSize)
                    || !isWordChar(buffer[prev]) || !isWordChar(buffer[next]))
            {
                error(1,0,"%d: Syntax error (Incomplete operators %c found)\n", lineNum, buffer[curr]);
            }
            break;
        case '&':
            if (buffer[next] == '&' && next-curr == 1)
            {
                buffer[curr] = '*';
                buffer[next] = ' ';
                next = nextIndex(buffer, bufferSize, curr);
                n = nextNonwhitespace(buffer, bufferSize, curr);
                if ((prev==-1) || (n==bufferSize)
                        || !(isWordChar(buffer[prev])||buffer[prev] == ')')  //(;) );(
                        || !(isWordChar(buffer[n])||buffer[n] == '('))
                {
                    error(1,0,"%d: Syntax error (Incomplete operators %c found)\n", lineNum, buffer[curr]);
                }
            }
            else
            {
                error(1,0,"%d: Syntax error (Incomplete operators %c found)\n", lineNum, buffer[curr]);
            }
            break;
        case '|':
            if (buffer[next] == '|' && next-curr == 1)
            {
                buffer[curr] = '$';
                buffer[next] = ' ';
                next = nextIndex(buffer, bufferSize, curr);
            }
            n = nextNonwhitespace(buffer, bufferSize, curr);
            if ((prev==-1) || (n==bufferSize)
                    || !(isWordChar(buffer[prev])||buffer[prev] == ')')  //(;) );(
                    || !(isWordChar(buffer[n])||buffer[n] == '('))
            {
                error(1,0,"%d: Syntax error (Incomplete operators %c found)\n", lineNum, buffer[curr]);
            }
            break;
        case '\n':
            if ((prev!=-1) && (buffer[prev] == '<' || buffer[prev] == '>'))
            {
                error(1,0,"%d: Syntax error (New line character can only follow tokens other than < >.)\n", lineNum);
            }

            if (buffer[next] == '\n')
            {
                if(buffer[prev] != '$' && buffer[prev] != '*' && buffer[prev] != '|')
                {
                    buffer[curr] = '@';
                }
                else
                {
                    buffer[curr] = ' ';
                }
                buffer[next] = ' ';
                lineNum++;
                next = nextIndex(buffer, bufferSize, next);
                while (buffer[next] == '\n')
                {
                    buffer[next] = ' ';
                    next = nextIndex(buffer, bufferSize, next);
                    lineNum++;
                }
            }
            else if ((prev!=-1) && (next!=bufferSize) && ((isOperator(buffer[prev])) || (buffer[prev]=='(')))
            {
                buffer[curr] = ' ';
            }
            else if ((prev!=-1) && (next!=bufferSize) && ((isWordChar(buffer[prev])) || (buffer[prev]==')')))
            {
                buffer[curr] = ';';
            }

            if ((next!=bufferSize)
                    && (!(buffer[next] == '(' || buffer[next]==')' || isWordChar(buffer[next]))))
            {
                error(1,0,"%d, Syntax error (New line character can only be followed by (, ), or Words.)\n", lineNum);
            }

            lineNum++;
            break;
        }
        prev = curr;
        curr = next;
        next = nextIndex(buffer, bufferSize, curr);
    }
    ////printf("Step 2: Buffer cleaned \n%s\n Strlen(buffer) = %d, bufferSize = %d\n", buffer, strlen(buffer), bufferSize);

    ////printf("Step 3: Parenthesis check start.\n");
    int stackSize = 0;
    int i;
    for (i = 0; i < bufferSize; i++)
    {
        if (buffer[i] == '(')
        {
            stackSize++;
        }
        else if (buffer[i] == ')')
        {
            if(stackSize > 0)
            {
                stackSize--;
            }
            else
            {
                error(1,0,"Syntax error (Unbalanced parenthesis found)\n");
            }
        }
    }
    if (stackSize > 0)
    {
        error(1,0,"Syntax error (Unbalanced parenthesis found)");
    }
    ////printf("Step 3: Parenthesis check complete.\n");

    ////printf("Step 4: Outputting\n");
    command_stream_t cstream = (command_stream_t) checked_malloc(sizeof(struct command_stream));
    cstream->stream = buffer;
    cstream->index = 0;
    if (debug) printf("Buffer: \"%s\"\n", buffer);

    return cstream;
}
Exemplo n.º 18
0
command_stream_t
make_command_stream (int (*get_next_byte) (void *),
		     void *get_next_byte_argument)
{
  /* FIXME: Replace this with your implementation.  You may need to
     add auxiliary functions and otherwise modify the source code.
     You can also use external functions defined in the GNU C Library.  */
  size_t buffer_size=1000;
  char* buffer = (char* )checked_malloc(buffer_size);
  size_t count = 0;
  char ch;

  do
  {
    ch = get_next_byte(get_next_byte_argument);

    if (ch == '#') // for comments: ignore everything until '\n' or EOF
    {
      ch = get_next_byte(get_next_byte_argument);
      while(ch != EOF && ch!='\n')
        ch = get_next_byte(get_next_byte_argument);
    }
    //skip all the words until \n
    if (ch!= -1)
    {
      // load into buffer
      buffer[count] = ch;
      count++;

      // expand buffer if necessary
      //if (count == INT_MAX)
      //{
      //  error(1, 0, "Line -1: Input size over INT_MAX.");
      //}
      if (count == buffer_size)
      {
        buffer_size = buffer_size * 2;
        buffer = (char*)checked_realloc (buffer, buffer_size);
      }
    }
  } while(ch != -1);

  token_stream_t return_token_stream = convert_buffer_to_token_stream(buffer, count);
  command_t new_command_t = make_command_tree (return_token_stream);
   // printf("make tree end\n");
  add_command_to_stream(new_command_t );
 // printf("add first command to stream\n");
 // printf("command type : %d\n", new_command_t->type);
  //if(new_command_t == NULL)
   // printf("HAHA");
 // print_command(new_command_t);
    while (return_token_stream->next != NULL)
  {
    //make return_point point to next token stream
    return_token_stream = return_token_stream->next;
    //free(return_point);
    //return_token_stream = temp;
    new_command_t = make_command_tree (return_token_stream);
    add_command_to_stream(new_command_t);
   // printf("add another command to stream\n");
    //print_command(new_command_t);
  }
//  printf("return to main\n");
 // print_command()
  return command_stream_head;

}
Exemplo n.º 19
0
token_stream_t 
convert_buffer_to_token_stream(char* buffer, size_t size)
{
//in this function convert buffer to the token stream, which is a linked list
  token_t head_token = create_token_with_type(HEAD, NULL, 0);//which created the dummy token 
    token_t curr_token = head_token;
    token_t prev_token = NULL;

    token_stream_head= (token_stream_t)checked_malloc(sizeof(token_stream_t));
    token_stream_t curr_stream = token_stream_head;
    curr_stream->head = head_token;
    curr_stream->tail = head_token;//now the head and tail both points to the head_token

    int line = 1;
    size_t index = 0;
    char c = *buffer;
    while(index<size)
    {   
      //printf("index=%d, size = %d",(int)index,(int)size);
      if(isword(c) )//if c is word
      {
        size_t word_length = 5 ;
        size_t word_position = 0;
        char *word = (char*)checked_malloc(sizeof(word_length));
        while(isword(c))
        {
          word[word_position] = c;//assign the c to corresponding position
        //  printf("test convert_buffer_to_token_stream1\n");
       // printf("c=%c \n",c);
          if(word_position == word_length)//if reaches the length
          {
            word_length*=2;
            word = (char*)checked_realloc(word,word_length);//resize the word length
          }
        word_position++;index++;buffer++;c = *buffer;//update the char and index
        
        }
        token_t now = create_token_with_type(WORD,word,line);
        curr_token ->next = now;
        prev_token = curr_token;//assign the previous token to now
        curr_token = curr_token->next;
        curr_token->prev = prev_token;
        prev_token->next = curr_token;
        curr_token->next = NULL;
        
      }
      else if(c == '\n')//if c is the new line
      {
        line++;
        if(curr_token->t_type ==LEFT_DERCTION||curr_token->t_type ==RIGHT_DERCTION)
          //LEFT direction and right direction cannot be followed by new line
          {
            error(2, 0, "Line %d: Newline cannot follow redirects.", line);
              return NULL;
            }
          //if the current token type is word or subshell which indicated a new command
            index++;
          if (index == size)
          {
          //  printf("break!" );
            break;
          }
          else
           { buffer++;c = *buffer;}
          if(curr_token->t_type==WORD||curr_token->t_type==SUBSHELL)
            {//create a new token stream
          curr_stream->next = (token_stream_t)checked_malloc(sizeof(token_stream_t));
                curr_stream = curr_stream->next;
                curr_stream->head = create_token_with_type(HEAD, NULL, -1);
                curr_token = curr_stream->head;
            }
          //else just treat is as white space
                 // printf("test convert_buffer_to_token_stream2 \n");
      //printf("c=%c \n",c);
          

      }
      else if(c == ' ' || c =='\t')
      {
        index++;buffer++;c = *buffer;
        //treated it as white space
      }
      else if(c == '<')//left direction
      {
        curr_token->next = create_token_with_type(LEFT_DERCTION,NULL,line);
      prev_token = curr_token;//assign the previous token to now
        curr_token = curr_token->next;
        curr_token->prev = prev_token;
        prev_token->next = curr_token;
        curr_token->next = NULL;
       // printf("test convert_buffer_to_token_stream3 \n");
   // printf("c=%c \n",c);
          buffer++; index++; c = *buffer;
      }
      else if (c == '>') // RIGHT REDIRECT
      {
          curr_token->next = create_token_with_type(RIGHT_DERCTION, NULL, line);
          prev_token = curr_token;//assign the previous token to now
        curr_token = curr_token->next;
        curr_token->prev = prev_token;
        prev_token->next = curr_token;
        curr_token->next = NULL;
      //  printf("test convert_buffer_to_token_stream3 \n");
   // printf("c=%c \n",c);
          buffer++; index++; c = *buffer;
      }
      else if (c == ';') // SEQUENCE command
      {
          curr_token->next = create_token_with_type(SEMICOLON, NULL, line);
          prev_token = curr_token;//assign the previous token to now
        curr_token = curr_token->next;
        curr_token->prev = prev_token;
        prev_token->next = curr_token;
        curr_token->next = NULL;
      //  printf("test convert_buffer_to_token_stream3 \n");
   // printf("c=%c \n",c);
          buffer++; index++; c = *buffer;
    
      }
       
      else if (c == '&') // and
      {
    //    printf("test convert_buffer_to_token_stream4 \n");
    //  printf("c=%c \n",c);
        buffer++; //my code 
        index++;
        c=*buffer;
        if(buffer[0]!='&')
        {
          error(2, 0, "Line %d: Syntax error. & must be followed by &", line);
            return NULL;
        }
        else if(buffer[0]=='&')
        {
            curr_token->next = create_token_with_type(AND, NULL, line);
            prev_token = curr_token;//assign the previous token to now
          curr_token = curr_token->next;
          curr_token->prev = prev_token;
          prev_token->next = curr_token;
          curr_token->next = NULL;
      //    printf("test convert_buffer_to_token_stream4 \n");
    //  printf("c=%c \n",c);
            buffer++; index++; c = *buffer;
          }
      
      }
      else if (c == '|') // OR or PIPELINE
      {
   //     printf("test convert_buffer_to_token_stream4 \n");
    // printf("c=%c \n",c);
        buffer++;
        index++;
        c=*buffer;
        
        if(buffer[0]=='|')
        {
            curr_token->next = create_token_with_type(OR, NULL, line);
            prev_token = curr_token;//assign the previous token to now
          curr_token = curr_token->next;
          curr_token->prev = prev_token;
          prev_token->next = curr_token;
          curr_token->next = NULL;
       //   printf("test convert_buffer_to_token_stream5 \n");
   //   printf("c=%c \n",c);
            buffer++; index++; c = *buffer;
          }
          else
        {
          curr_token->next = create_token_with_type(PIPELINE, NULL, line);
            prev_token = curr_token;//assign the previous token to now
          curr_token = curr_token->next;
          curr_token->prev = prev_token;
          prev_token->next = curr_token;
          curr_token->next = NULL;
            //buffer++; index++; c = *buffer;
        }
        /*  else
        {
          error(2, 0, "Line %d: Syntax error. | only can be followed by | or  ", line);
            return NULL;
        }*/
      }
      else if (c == '(') // SUBSHELL
      {
          int subshell_line = line;
          int nested = 1;

          size_t count = 0;
          size_t subshell_size = 64;
          char* subshell = (char*)checked_malloc(subshell_size);

          // grab contents until subshell is closed
          while (nested > 0)
          {
            buffer++; index++; c = *buffer;
            //to examine the next char
            if (index == size)
              {
                  error(2, 0, "Line %d: Syntax error. EOF reached before subshell was closed.", subshell_line);
                  return NULL;
              }

            if (c == '\n')
            {
                // consume all following whitespace
                while (buffer[1] == ' ' || buffer[1] == '\t' || buffer[1] == '\n')
                {
                  if (buffer[1] == '\n')
                    line++;

                buffer++;
                index++;
                }

                // pass semicolon
                c = ';';
                line++;
            }
            else if (c == '(') // count for nested subshells
                nested++;
            else if (c == ')') // close subshell
            {
                nested--;

              if (nested == 0) // break if outermost subshell is closed
              {
                buffer++; index++; c = *buffer; // consume last close parens
                break;
              }
            }
// printf("test convert_buffer_to_token_stream6 \n");
 //printf("c=%c \n",c);
        // load into subshell buffer
        subshell[count] = c;
        count++;

        // expand subshell buffer if necessary
        if (count == subshell_size)
        {
          subshell_size = subshell_size * 2;
          subshell = (char*)checked_realloc (subshell, subshell_size);
        }
      //  printf("test convert_buffer_to_token_stream7 \n");
     //   printf("c=%c \n",c);
      }

      // create subshell token
      curr_token->next = create_token_with_type(SUBSHELL, subshell, subshell_line);
     // curr_token = curr_token->next;
      prev_token = curr_token;//assign the previous token to now
          curr_token = curr_token->next;
          curr_token->prev = prev_token;
          prev_token->next = curr_token;
          curr_token->next = NULL;
    }
    else if (c == ')') // CLOSE PARENS
    {
      error(2, 0, "Line %d: Syntax error. Close parens found without matching open parens.", line);
      return NULL;
    }
		else 
	{
		error(2, 0, "Line %d: Syntax error. Unrecognized character in script. ", line);
		return NULL;
	}
    }

  //  printf("return headstream");
    return token_stream_head;
}
Exemplo n.º 20
0
void increase_file_array(FileArray* n)
{
    n->size *=2;
    
    n->files = checked_realloc(n->files, n->size*sizeof(*n->files));
}
Exemplo n.º 21
0
command_t
parse_token_to_command(token_stream_t tst)
{
	token_t next_token = token_stream_current(tst);
	if (!next_token)
		return NULL;
		
	command_t head;
	command_t cur = NULL;
	command_t prev;
	
	while (next_token)
	{
		char *current_token_char = next_token->string;
		int current_token_type = next_token->type;
	
		int num_words = 1;
		int phrase_index = 0;
		int status = -1;
		char **phrase = checked_malloc((num_words + 1) * sizeof(char*));
		char *input = NULL, *output= NULL;
		
		command_t temp = checked_malloc(sizeof(struct command));
		command_t temp_sub;
		
		
		phrase[phrase_index + 1] = NULL;
		switch (next_token->type)
		{
			case WORD:
			{
				phrase[phrase_index] = next_token->string;
				phrase_index++;
				
				token_stream_read(tst);
				free(next_token);
				next_token = token_stream_current(tst);
				
				while (next_token && next_token->type == WORD)
				{
					num_words++;
					phrase = checked_realloc(phrase, (num_words + 1) * sizeof(char*));
					phrase[phrase_index + 1] = NULL;
					
					phrase[phrase_index] = next_token->string;
					phrase_index++;
					
					token_stream_read(tst);
					free(next_token);
					next_token = token_stream_current(tst);
				}
				
				if (next_token && next_token->type == IN)
				{
					token_stream_read(tst);
					free_token(next_token);
					next_token = token_stream_current(tst);
					
					input = next_token->string;
					
					token_stream_read(tst);
					free(next_token);
					next_token = token_stream_current(tst);
				}
				
				if (next_token && next_token->type == OUT)
				{
					token_stream_read(tst);
					free_token(next_token);
					next_token = token_stream_current(tst);
					
					output = next_token->string;
					
					token_stream_read(tst);
					free(next_token);
					next_token = token_stream_current(tst);
				}
				
				temp->type = SIMPLE_COMMAND;
				temp->status = status;
				temp->input = input;
				temp->output = output;
				temp->u.word = phrase;
				break;
			}
			case OPEN_PAREN:
			{
				token_stream_read(tst);
				free_token(next_token);
				next_token = token_stream_current(tst);
				
				temp_sub = parse_token_to_command(tst);
				next_token = token_stream_current(tst);
				
				current_token_char = next_token->string;
				current_token_type = next_token->type;
				
				if (next_token && next_token->type == IN)
				{
					token_stream_read(tst);
					free_token(next_token);
					next_token = token_stream_current(tst);
					
					input = next_token->string;
					
					token_stream_read(tst);
					free(next_token);
					next_token = token_stream_current(tst);
				}
				
				if (next_token && next_token->type == OUT)
				{
					token_stream_read(tst);
					free_token(next_token);
					next_token = token_stream_current(tst);
					
					output = next_token->string;
					
					token_stream_read(tst);
					free(next_token);
					next_token = token_stream_current(tst);
				}
				
				temp->type = SUBSHELL_COMMAND;
				temp->status = status;
				temp->input = input;
				temp->output = output;
				temp->u.subshell_command = temp_sub;
				break;
			}
			case CLOSE_PAREN:
			{
				token_stream_read(tst);
				free_token(next_token);
				next_token = token_stream_current(tst);
				
				return head;
			}
			case PIPE:
			{
				temp->type = PIPE_COMMAND;
				temp->status = status;
				
				token_stream_read(tst);
				free_token(next_token);
				next_token = token_stream_current(tst);
				break;
			}
			case OR:
			{
				temp->type = OR_COMMAND;
				temp->status = status;
				
				token_stream_read(tst);
				free_token(next_token);
				next_token = token_stream_current(tst);
				break;
			}
			case AND:
			{
				temp->type = AND_COMMAND;
				temp->status = status;
				
				token_stream_read(tst);
				free_token(next_token);
				next_token = token_stream_current(tst);
				break;
			}
			case SEQ:
			{
				temp->type = SEQUENCE_COMMAND;
				temp->status = status;
				
				token_stream_read(tst);
				free_token(next_token);
				next_token = token_stream_current(tst);
				
				if (!next_token || next_token->type == NEWLINE || next_token->type == CLOSE_PAREN)
				{
					token_stream_read(tst);
					free_token(next_token);
					next_token = token_stream_current(tst);
					return head;
				}
				
				break;
			}
			case NEWLINE:
			{
				token_stream_read(tst);
				free_token(next_token);
				next_token = token_stream_current(tst);
				return head;
				break;
			}
		}
		
		if (!cur)
		{
			cur = temp;
			head = cur;
		}
		else if (precedence_command(temp) <= precedence_command(cur))
		{
			if (head != cur)
				cur = head;
			prev = cur;
			cur = temp;
			head = cur;
			cur->u.command[0] = prev;
		}
		else if (precedence_command(temp) > precedence_command(cur))
		{
			if (!cur->u.command[1])
				cur->u.command[1] = temp;
			else
			{
				temp->u.command[0] = cur->u.command[1];
				cur->u.command[1] = temp;
				prev = cur;
				cur = temp;
			}
		}
	}
	return head;
}
Exemplo n.º 22
0
/* FIXME: Define the type 'struct command_stream' here. This should
complete the incomplete type declaration in command.h. */
command_stream_t make_command_stream(int(*get_next_byte) (void *),
	void *get_next_byte_argument)
{
	/* FIXME: Replace this with your implementation. You may need to
	add auxiliary functions and otherwise modify the source code.
	You can also use external functions defined in the GNU C Library. */
	if (DEBUG) printf("291 Begin make_command_stream\n");
	initStream();
	size_t sizeofBuffer = 1024;
	char* buffer = (char*)checked_malloc(sizeofBuffer);
	char curr;
	size_t filled = 0;
	while ((curr = get_next_byte(get_next_byte_argument)) != EOF) {
		buffer[filled] = curr;
		filled++;
		if (filled == sizeofBuffer) {
			sizeofBuffer *= 2;
			buffer = (char*)checked_grow_alloc(buffer, &sizeofBuffer);
		}
	}
	//***For the parser:
	//Word
	int bufferWordSize = 10;
	int currWord = 0;
	//char ** wordElement;
	char** wordElement = checked_malloc(sizeof(char*));
	wordElement[currWord] = (char*)checked_malloc(bufferWordSize);
	int usedWord = 0;
	//Input
	int bufferInputSize = 10;
	char* inputElement = (char*)checked_malloc(bufferInputSize);
	int usedInput = 0;
	//Output
	int bufferOutputSize = 10;
	char* outputElement = (char*)checked_malloc(bufferOutputSize);
	int usedOutput = 0;
	//***Initialize operator and command stacks
	initStacks();
	if (DEBUG) printf("333 Buffer created, initStacks()\n");
	
	int i = 0;
	while (i < (int)filled)
	{
		if (DEBUG) printf("on buffer %d\n", i);
		//***When you want to add a character*************************//
		int op = -1;
		int openCount = 0;
		int closedCount = 0;

		if (buffer[i] == '`')
			error(1, 0, "Line %d: %c", __LINE__, buffer[i]);

		if (buffer[i] == '(')
		{
			openCount = 1;
			closedCount = 0;
			int x = i;
			while (x < (int) filled)
			{
				x++;
				if (buffer[x] == '(')
					openCount++;
				if (buffer[x] == ')')
					closedCount++;
				if (closedCount == openCount)
					break;
			}
			if (closedCount != openCount)
				error(1, 0, "Line %d: Expected ')' for end of subshell", __LINE__);
		}
		if(buffer[i] == ')')
		{
			if(openCount == 0)
				error(1, 0, "Line %d: Expected '(' before ')'", __LINE__);
		}

		if(buffer[i] = '(') 
		{
			op = numberOfOper(&buffer[i]);
			processOperator(op);
		}

		//Case of ' '
		while (buffer[i] == ' ' && usedWord == 0)
			i++;

		if (buffer[i] == ' ' && usedWord != 0)
		{
			if (usedWord >= bufferWordSize)
			{
				bufferWordSize += 10;
				wordElement[currWord] = (char*)checked_realloc(wordElement[currWord], bufferWordSize);
			}
			//i++;
			wordElement[currWord][usedWord] = '\0';
			while (buffer[i + 1] == ' ')
				i++;
			usedWord = 0;
			bufferWordSize = 10;
			currWord++;
			wordElement[currWord] = (char*)checked_malloc(bufferWordSize);
			//wordElement[currWord][usedWord] = buffer[i];
			//usedWord++;
		}
		//Case of carrots
		//WHAT IF a<b>c>d<a....?! You're making a simple command out of a<b>c which then
		// must also be the word of >d<a
		//Case of '<' first
		else
			if (buffer[i] == '<')
			{
				int k = i;
				while (buffer[k-1] == ' ')
				{
					k--;
					if(buffer[k-1] == '\n')
						error(1, 0, "Line %d: Operator and word on diff lines", __LINE__);
				}
				if (wordElement[0][0] == '\0')
					error(1, 0, "Line %d: No command given to '<'", __LINE__);
				i++;
				while (buffer[i] != '<' && buffer[i] != '>' && buffer[i] != '&' && buffer[i] != '|' && buffer[i] != '(' && buffer[i] != ')' && buffer[i] != ';' && buffer[i] != '\n')
				{
					if (i == filled)
					{
						if (DEBUG) printf("378 Complete command, free buffer bc EOF\n");
						currWord++;
						wordElement[currWord] = '\0';
						if (usedInput == 0)
							inputElement = NULL;
						if (usedOutput == 0)
							outputElement = NULL;
						makeSimpleCommand(wordElement, inputElement, outputElement);
						completeCommand();
						//free(buffer);
						return headStream;
					}
					if (buffer[i] == ' ')
						i++;
					else
					{
						if (usedInput >= bufferInputSize)
						{
							bufferInputSize += 10;
							inputElement = (char*)checked_realloc(inputElement, bufferInputSize);
						}
						inputElement[usedInput] = buffer[i];
						usedInput++;
						i++;
					}
				}
				if (usedInput >= bufferInputSize)
				{
					bufferInputSize += 10;
					inputElement = (char*)checked_realloc(inputElement, bufferInputSize);
				}
				if (usedInput == 0)
					error(1, 0, "Line %d: No input after '<'", __LINE__);
				inputElement[usedInput] = '\0';
				usedInput++;
				if (buffer[i] == '>')
				{
					i++;
					while (buffer[i] != '<' && buffer[i] != '>' && buffer[i] != '&' && buffer[i] != '|' && buffer[i] != '(' && buffer[i] != ')' && buffer[i] != ';' && buffer[i] != '\n')
					{
						if (i == filled)
						{
							if (DEBUG) printf("413 Complete command, free buffer at EOF\n");
							currWord++;
							wordElement[currWord] = '\0';
							if (usedInput == 0)
								inputElement = NULL;
							if (usedOutput == 0)
								outputElement = NULL;
							makeSimpleCommand(wordElement, inputElement, outputElement);
							completeCommand();
							//free(buffer);
							return headStream;
						}
						if (buffer[i] == ' ')
							i++;
						else
						{
							if (usedOutput >= bufferOutputSize)
							{
								bufferOutputSize += 10;
								outputElement = (char*)checked_realloc(outputElement, bufferOutputSize);
							}
							outputElement[usedOutput] = buffer[i];
							usedOutput++;
							i++;
						}
					}
					if (usedOutput >= bufferOutputSize)
					{
						bufferOutputSize += 10;
						outputElement = (char*)checked_realloc(outputElement, bufferOutputSize);
					}
					if (usedOutput == 0)
						error(1, 0, "Line %d: No input after '<'", __LINE__);
					outputElement[usedOutput] = '\0';
					usedOutput++;
					//i--; //Check logic
				}
				i--;
			}
		/////CHECK FOR EXTRA i++!!!!!
		//Case of '>' first
			else
				if (buffer[i] == '>')
				{
					int k = i;
					while (buffer[k-1] == ' ')
					{
						k--;
						if(buffer[k-1] == '\n')
							error(1, 0, "Line %d: Operator and word on diff lines", __LINE__);
					}
					if (wordElement[0][0] == '\0')
					error(1, 0, "Line %d: No command given to '<'", __LINE__);
					i++;
					while (buffer[i] != '<' && buffer[i] != '>' && buffer[i] != '&' && buffer[i] != '|' && buffer[i] != '(' && buffer[i] != ')' && buffer[i] != ';' && buffer[i] != '\n')
					{
						if (i == filled)
						{
							if (DEBUG) printf("471 Complete Command, free buffer at EOF");
							currWord++;
							wordElement[currWord] = '\0';
							if (usedInput == 0)
								inputElement = NULL;
							if (usedOutput == 0)
								outputElement = NULL;
							makeSimpleCommand(wordElement, inputElement, outputElement);
							completeCommand();
							//free(buffer);
							return headStream;
						}
						if (buffer[i] == ' ')
							i++;
						else
						{
							if (usedOutput >= bufferOutputSize)
							{
								bufferOutputSize += 10;
								outputElement = (char*)checked_realloc(outputElement, bufferOutputSize);
							}
							outputElement[usedOutput] = buffer[i];
							usedOutput++;
							i++;
						}
					}
					if (usedOutput >= bufferOutputSize)
					{
						bufferOutputSize += 10;
						outputElement = (char*)checked_realloc(outputElement, bufferOutputSize);
					}
					if (usedOutput == 0)
						error(1, 0, "Line %d: No input after '<'", __LINE__);
					outputElement[usedOutput] = '\0';
					usedOutput++;
					if (buffer[i] == '<')
					{
						i++;
						while (buffer[i] != '<' && buffer[i] != '>' && buffer[i] != '&' && buffer[i] != '|' && buffer[i] != '(' && buffer[i] != ')' && buffer[i] != ';' && buffer[i] != '\n')
						{
							if (i == filled)
							{
								if (DEBUG) printf("505 Complete Command, free buffer at EOF");
								currWord++;
								wordElement[currWord] = '\0';
								if (usedInput == 0)
									inputElement = NULL;
								if (usedOutput == 0)
									outputElement = NULL;
								makeSimpleCommand(wordElement, inputElement, outputElement);
								completeCommand();
								//free(buffer);
								return headStream;
							}
							if (buffer[i] == ' ')
								i++;
							else
							{
								if (usedInput >= bufferInputSize)
								{
									bufferInputSize += 10;
									inputElement = (char*)checked_realloc(inputElement, bufferInputSize);
								}
								inputElement[usedInput] = buffer[i];
								usedInput++;
								i++;
							}
						}
						if (usedInput >= bufferInputSize)
						{
							bufferInputSize += 10;
							inputElement = (char*)checked_realloc(inputElement, bufferInputSize);
						}
						if (usedInput == 0)
							error(1, 0, "Line %d: No input after '<'", __LINE__);
						inputElement[usedInput] = '\0';
						usedInput++;
					}
					wordElement[currWord + 1] = '\0';
					/*if (usedInput == 0)
					inputElement = NULL;
					if (usedOutput == 0)
					outputElement = NULL;
					if(DEBUG) printf("makeSimpleCommand %s\n", wordElement[0]);
					makeSimpleCommand(wordElement, inputElement, outputElement);
					bufferWordSize = 10;
					currWord = 0;
					usedWord = 0;
					usedInput = 0;
					usedOutput = 0;
					wordElement = (char**)checked_malloc(sizeof(char*));
					wordElement[currWord] = (char*)checked_malloc(bufferWordSize);
					inputElement = (char*)checked_malloc(bufferInputSize);
					outputElement = (char*)checked_malloc(bufferOutputSize);*/
					i--;
				}
		//Operators
		//After every operator is encountered, use makeSimpleCommand to push the command on the stack
		//Case of '|'
				else
					if (buffer[i] == '|')
					{
						int k = i;
						while (buffer[k-1] == ' ')
						{
							k--;
							if(buffer[k-1] == '\n')
								error(1, 0, "Line %d: Operator and word on diff lines", __LINE__);
						}
						
						if (buffer[i+1] == '|' && operatorStack == NULL)
							error(1, 0, "Line %d: Missing pipe for '||'", __LINE__);
						if (wordElement[0][0] == '\0')
							error(1, 0, "Line %d: Nothing for '|'", __LINE__);
						//if (commandStack == NULL)
						//	error(1, 0, "Line %d: Nothing to run '|' on");
						if (buffer[i + 1] == '|' && buffer[i+2] == '|')
							error(1, 0, "Line %d: Invalid Command, too many '|'", i);
						op = numberOfOper(&buffer[i]);
						//error(1, 0, "Line %d: Nothing to pipe", __LINE__);
						if (buffer[i-1] != ' ')
							currWord++;
						wordElement[currWord] = '\0';
						if (usedInput == 0)
							inputElement = NULL;
						if (usedOutput == 0)
							outputElement = NULL;
						if (DEBUG) printf(" 566 makeSimpleCommand %s\n", wordElement[0]);
						makeSimpleCommand(wordElement, inputElement, outputElement);
						bufferWordSize = 10;
						currWord = 0;
						usedWord = 0;
						usedInput = 0;
						usedOutput = 0;
						wordElement = (char**)checked_malloc(sizeof(char*));
						wordElement[currWord] = (char*)checked_malloc(bufferWordSize);
						inputElement = (char*)checked_malloc(bufferInputSize);
						outputElement = (char*)checked_malloc(bufferOutputSize);
						if (DEBUG) printf("577 Process operator %d\n", op);
						processOperator(op);
						if (op == 3) 
							i++;
						if (buffer[i + 1] == ' ')
							i++;
						//i++;
					}
		//Case of '&'
					else
						if (buffer[i] == '&')
						{
							int k = i;
							while (buffer[k-1] == ' ')
							{
								k--;
								if(buffer[k-1] == '\n')
									error(1, 0, "Line %d: Operator and word on diff lines", __LINE__);
							}
							//if (buffer[i] == '&' && operatorStack == NULL)
							//	error(1, 0, "Line %d: Missing pipe for '&&'", __LINE__);
							if (wordElement[0][0] == '\0')
								error(1, 0, "Line %d: Nothing for '|'", __LINE__);
							if (buffer[i + 1] == '&' && buffer[i+2] == '&')
								error(1, 0, "Line %d: Invalid Command, too many '&'", i);
							op = numberOfOper(&buffer[i]);
							if (buffer[i-1] != ' ')
								currWord++;
							wordElement[currWord] = '\0';
							if (usedInput == 0)
								inputElement = NULL;
							if (usedOutput == 0)
								outputElement = NULL;
							if (DEBUG) printf("592 makeSimpleCommand %s\n", wordElement[0]);
							makeSimpleCommand(wordElement, inputElement, outputElement);
							bufferWordSize = 10;
							usedWord = 0;
							currWord = 0;
							usedInput = 0;
							usedOutput = 0;
							wordElement = (char**)checked_malloc(sizeof(char*));
							wordElement[currWord] = (char*)checked_malloc(bufferWordSize);
							inputElement = (char*)checked_malloc(bufferInputSize);
							outputElement = (char*)checked_malloc(bufferOutputSize);
							processOperator(op);
							i++;
							if (buffer[i + 1] == ' ')
								i++;
						}
		//Case of ';'
						else
							if (buffer[i] == ';')
							{
													int k = i;
						while (buffer[k-1] == ' ')
						{
							k--;
							if(buffer[k-1] == '\n')
								error(1, 0, "Line %d: Operator and word on diff lines", __LINE__);
						}
								if(wordElement[0][0] == '\0')
									error(1, 0, "Line %d: Nothing before sequence", i);
								op = numberOfOper(&buffer[i]);
								currWord++;
								wordElement[currWord] = '\0';
								if (usedInput == 0)
									inputElement = NULL;
								if (usedOutput == 0)
									outputElement = NULL;
								if (DEBUG) printf("617 makeSimpleCommand %s\n", wordElement[0]);
								if ((currWord = 0) || (currWord == 1))
									error(1, 0, "Line %d: Nothing to run ';' on", i);
								makeSimpleCommand(wordElement, inputElement, outputElement);
								bufferWordSize = 10;
								usedWord = 0;
								currWord = 0;
								usedInput = 0;
								usedOutput = 0;
								wordElement = (char**)checked_malloc(sizeof(char*));
								wordElement[currWord] = (char*)checked_malloc(bufferWordSize);
								inputElement = (char*)checked_malloc(bufferInputSize);
								outputElement = (char*)checked_malloc(bufferOutputSize);
								processOperator(op);
								//i++;
							}
		//Case of '\n'
							else
								if (buffer[i] == '\n' && i != 0)
								{
									/*int scChecker = i;
									while (buffer[i + 1] == ' ')
									{
										scChecker++;
										if (buffer[scChecker + 1] == ';')
											error(1, 0, "Line %d: Newline followed by ';'");
									}*/
									if (buffer[i+1] == ';')
										error(1, 0, "Line %d: Newline followed by ';'", i);
									if ((i + 1) == (int)filled)
									{
										currWord++;
										wordElement[currWord] = '\0';
										if (usedInput == 0)
											inputElement = NULL;
										if (usedOutput == 0)
											outputElement = NULL;
										if (DEBUG) printf("654 makeSimpleCommand %s\n", wordElement[0]);
										makeSimpleCommand(wordElement, inputElement, outputElement);
										bufferWordSize = 10;
										currWord = 0;
										usedWord = 0;
										usedInput = 0;
										usedOutput = 0;
										wordElement = (char**)checked_malloc(sizeof(char*));
										wordElement[currWord] = (char*)checked_malloc(bufferWordSize);
										inputElement = (char*)checked_malloc(bufferInputSize);
										outputElement = (char*)checked_malloc(bufferOutputSize);
										completeCommand();
										free(buffer);
										return headStream;
									}
									char lastC;
									int back = 1;
									while (buffer[i - back] == ' ' && i - back >= 0)
									{
										//lastC = buffer[i - back];
										back++;
									}
									lastC = buffer[i - back];
									if (buffer[i + 1] == '\n')
									{
										while (buffer[i + 1] == '\n')
											i++;
										if (lastC != '|' && lastC != '&')
										{
											currWord++;
											wordElement[currWord] = '\0';
											if (usedInput == 0)
												inputElement = NULL;
											if (usedOutput == 0)
												outputElement = NULL;
											if (DEBUG) printf("654 makeSimpleCommand %s\n", wordElement[0]);
											makeSimpleCommand(wordElement, inputElement, outputElement);
											bufferWordSize = 10;
											currWord = 0;
											usedWord = 0;
											usedInput = 0;
											usedOutput = 0;
											wordElement = (char**)checked_malloc(sizeof(char*));
											wordElement[currWord] = (char*)checked_malloc(bufferWordSize);
											inputElement = (char*)checked_malloc(bufferInputSize);
											outputElement = (char*)checked_malloc(bufferOutputSize);
											completeCommand();
										}
									}
									else
									{
										if (lastC == '|' || lastC == '&' || lastC == '<' || lastC || '>')
										{
											while (buffer[i + 1] == '\n')
												i++;//////SPIT ERROR?
										}
										else
										{
											char swap = ';';
											op = numberOfOper(&swap);
											wordElement[currWord + 1] = '\0';
											if (usedInput == 0)
												inputElement = NULL;
											if (usedOutput == 0)
												outputElement = NULL;
											if (DEBUG) printf(" 679 makeSimpleCommand %s\n", wordElement[0]);
											makeSimpleCommand(wordElement, inputElement, outputElement);
											bufferWordSize = 10;
											currWord = 0;
											usedWord = 0;
											usedInput = 0;
											usedOutput = 0;
											wordElement = (char**)checked_malloc(sizeof(char*));
											wordElement[currWord] = (char*)checked_malloc(bufferWordSize);
											inputElement = (char*)checked_malloc(bufferInputSize);
											outputElement = (char*)checked_malloc(bufferOutputSize);
											processOperator(op);
										}
									}
								}
		//Case of # (comment)
								else
									if (buffer[i] == '#')
									{
										if (DEBUG) printf("698 Got a comment!\n");
										while (buffer[i] != '\n')
											i++;
									}
									//Else
									else
									{
										if (buffer[i] == '\'')
										{
											if (buffer[i + 1] == 'E' && buffer[i + 2] == 'O' && buffer[i + 3] == 'F')
												break;
										}
										//if (buffer[i] != ' ')
										wordElement[currWord][usedWord] = buffer[i];
										usedWord++;
										if (i + 1 == filled)
										{
											currWord++;
											wordElement[currWord] = '\0';
											if (usedInput == 0)
												inputElement = NULL;
											if (usedOutput == 0)
												outputElement = NULL;
											makeSimpleCommand(wordElement, inputElement, outputElement);
											completeCommand();
										}
									}
		i++;
	}
	free(buffer);
	return headStream;
}
Exemplo n.º 23
0
bool increaseSize(char* element, int used, int* bufferSize)
{
	*bufferSize += 10;
	element = (char*)checked_realloc(element, 10 * (*bufferSize));
	return true;
}
Exemplo n.º 24
0
//creates the command struct based on tokens passed in
command_t make_command(char *token, command_t subcommand)
{	
	//checks for more than one <, >
	containsCarrot(token);
	command_t cmdStruct = checked_malloc(sizeof(struct command));
	//for subshell
	if(token == NULL){
		cmdStruct->type = SUBSHELL_COMMAND;
		cmdStruct->input = 0;
		cmdStruct->output = 0;
		cmdStruct->u.subshell_command = subcommand;
		return cmdStruct;
	}
	int tokenTracker = 0;
	//if token starts with spaces...
	int i;
	for(i = 0; isWhiteSpace(token[i]); i++){        
		tokenTracker++;
	}
	int start = tokenTracker;
	char* command = checked_malloc(50);
	tokenTracker = getNextWord(tokenTracker, token, &command);
	if(command[0] == '&'){
		cmdStruct->type = AND_COMMAND;
		cmdStruct->input = 0;
		cmdStruct->output = 0;
	} else if (command[0] == '|'){
		if(command[1] == '|'){
			cmdStruct->type = OR_COMMAND;
		} else {
            cmdStruct->type = PIPE_COMMAND;
		}
		cmdStruct->input = 0;
		cmdStruct->output = 0;
	} else if (command[0] == ';'){
		cmdStruct->type = SEQUENCE_COMMAND;
		cmdStruct->input = 0;
		cmdStruct->output = 0;
    } else if (command[0] == '<' || command[0] == '>'){
		fprintf(stderr, "%d: Incorrect syntax2 \n", line_number);
		exit(1);
	} else {
			cmdStruct->type = SIMPLE_COMMAND;
			int bufferSize = 10;
			char** wordArray = checked_malloc(sizeof(char*)*10);
			int numberOfWords = 0;
			wordArray[numberOfWords] = checked_malloc(tokenTracker+ 1); 
			command[tokenTracker] = '\0';
			if(containsCarrot(command)){
				 int buffSize = 50;
                 char* com = checked_malloc(buffSize);
                 int comstart = 0;
                 while(command[comstart] != '<' && command[comstart]!= '>'){
						if(comstart >= buffSize){
							buffSize += 50;
							com = checked_realloc(com, sizeof(char*)*buffSize);
						}
                        com[comstart] = command[comstart];
                        comstart++;
                 }
				 wordArray[numberOfWords] = com;
				tokenTracker = tokenTracker - 2 ;
            } else{
				wordArray[numberOfWords] = command;
			}
			numberOfWords++;
			while(token[tokenTracker] != '\0'){
					char* word = checked_malloc(50);
					tokenTracker++;
					start = tokenTracker;
					tokenTracker = getNextWord(tokenTracker, token, &word);
					if(word[0] != '<' && word[0] != '>' && (word[tokenTracker-start-1] == '<' || word[tokenTracker-start-1]  == '>')){
						word[tokenTracker-start-1] = '\0';
						tokenTracker = tokenTracker-2; 
					} else{	
						word[tokenTracker-start] = '\0';
					}
				if(word[0] == '<'){
		 			char* in = checked_malloc(50);
					tokenTracker = getInputOutput(tokenTracker, token, &in); 
					cmdStruct->input = in;
            	} else if (word[0] == '>'){
		 			char* output = checked_malloc(50);
					tokenTracker = getInputOutput(tokenTracker, token, &output);
                	cmdStruct->output = output;
            	} else {
					if(numberOfWords >= bufferSize){
                	bufferSize += 50;
                	wordArray = checked_realloc(wordArray, sizeof(char*)*bufferSize);
					}
               		if(word[0] != '\0'){        
                    	wordArray[numberOfWords] = checked_malloc(tokenTracker-start);
                    	wordArray[numberOfWords] = word;
                    	numberOfWords++;
						cmdStruct->input = 0;
						cmdStruct->output = 0;
               		}
            	}
        }
        wordArray[numberOfWords] = '\0';
        cmdStruct->u.word = wordArray;
	}
	return cmdStruct;
}
Exemplo n.º 25
0
command_t
parseCmd(char *start, char *end) {
    if (start>end/* || iters++>MAXITER*/) return NULL;

    //trim the start and end pointers
    start=skipWs(start);

    if (*start=='\0') return NULL;

    while (*end == ' ' || *end == '\t' || *end == '\n')
    {
        end--;
    }

    if (debug) printf("parsing: \"%.*s\" start = \'%c\' end = \'%c\'\n", end-start+1, start, *start, *end);

    command_t t = (command_t) checked_malloc(sizeof(struct command));
    char *ptr = start;
    //char *op = findNextOperator(ptr);
    char *op = strpbrk(skipSubshell(ptr), ";$*|");
    char *next = op;

    ////printf("parsing: start = %c op = %c next = %c \n", *ptr, *op, *next);

    while (next && next <= end) {

        char * prec = ";$*|";
        int opPrec = strchr(prec, *op) - prec;
        int nextPrec = strchr(prec, *next) - prec;
        //printf("parsing: [while] opPrec = %d nextPrec = %d \n", opPrec, nextPrec);
        if (((opPrec == 1 || opPrec == 2) && (nextPrec == 1 || nextPrec == 2))
                || (nextPrec < opPrec))
        {
            op = next;
        }
        //printf("parsing: [while] start = %c op = %c next = %c \n", *ptr, *op, *next);
        //next = findNextOperator(++next);
        next = strpbrk(skipSubshell(++next), ";$*|");

    }

    if (op && op<end) { // if operator in expression
        //////printf("op: %c\n",*op);
        switch(*op) {
        case ';':
            t->type=SEQUENCE_COMMAND;
            break;
        case '$':
            t->type=OR_COMMAND;
            break;
        case '*':
            t->type=AND_COMMAND;
            break;
        case '|':
            t->type=PIPE_COMMAND;
            break;
        default:
            error(1,0,"illegal operator detected");
            //should not get here
            break;
        }
        //printf("\ncomplex command type%d: %.*s,%.*s\n", t->type, op-start, start,end-op,op+1);
        //t->u.command=(command_t *) checked_malloc(sizeof(command_t)*2);

        t->u.command[0]=parseCmd(start,op-1);
        t->u.command[1]=parseCmd(op+1,end);


    } else if (*start == '(') { //if subshell
        //printf("subshell command\n");
        ptr = skipSubshell(ptr);
        t->type=SUBSHELL_COMMAND;
        t->u.subshell_command=(command_t) checked_malloc(sizeof(command_t));
        t->u.subshell_command=parseCmd(start+1,ptr-1);
    } else { //simple command with no op and no subshell
        //if (debug) printf("Building simple command\n");
        t->type=SIMPLE_COMMAND;

        int wdct=0;//word count tracker

        //construct the simple command struct from str - check for redirections
        char* s = start;
        char* e;

        while (s)
        {

            if(*s == '<')
            {
                s = nextWordStart(s, end);
                e = currWordEnd(s, end);
                size_t wsize = e-s+1;
                t->input=(char *) checked_malloc(wsize+1);
                memcpy(t->input,s,wsize);
                t->input[wsize]='\0';
                if(debug) printf("Building segments: \"%.*s\" -> \'%s\'\n", e-s+1, s, t->input);

            }
            else if(*s == '>')
            {
                s = nextWordStart(s, end);
                e = currWordEnd(s, end);
                size_t wsize = e-s+1;
                t->output=(char *) checked_malloc(wsize+1);
                memcpy(t->output,s,wsize);
                t->output[wsize]='\0';
                if(debug) printf("Building segments: \"%.*s\" -> \'%s\'\n", e-s+1, s, t->output);
            }
            else
            {
                e = currWordEnd(s, end);
                size_t wsize = e-s+1;
                size_t asize = sizeof(char*) * (wdct+2);
                t->u.word = (char **) checked_realloc(t->u.word, asize);
                t->u.word[wdct] = (char *) checked_malloc(wsize+1);
                memcpy(t->u.word[wdct],s,wsize);
                t->u.word[wdct][wsize]='\0';
                wdct++;
                if(debug) printf("Building segments: \"%.*s\" -> \'%s\'\n", e-s+1, s, t->u.word[wdct-1]);
            }
            s = nextWordStart(e, end);
        }
        *(t->u.word+wdct)=NULL;
    }
    return t;
}
Exemplo n.º 26
0
//reads entire command until operators
char* read_token (int (*get_next_byte) (void *),
         void *get_next_byte_argument, int *pos, int check_newline)
{
	char c;
	int tmp_pos = *pos;
	int tmpSize = 50;
	char *token = (char*)checked_malloc(sizeof(char)*tmpSize);
	c = get_next_byte(get_next_byte_argument);
	char *paren = (char*)checked_malloc(sizeof(char));
	if(!isValid(c)){
		fprintf(stderr, "%d: Invalid Syntax", line_number);
		exit(1);
	}

	if(check_newline == 0)
	{
		while(!isOperator(c) && c != EOF && c != '\n' && c !=')')
		{
			if (c == '('){
				paren[0] = '(';
				return paren;
			}
			if(tmp_pos > tmpSize){
				tmpSize += 50;
				token = (char*) checked_realloc(token, sizeof(char)*tmpSize);
			}
  			token[tmp_pos] = c;
  			tmp_pos++;
			c = get_next_byte(get_next_byte_argument);
			if(!isValid(c)){
		                fprintf(stderr, "%d: Invalid Syntax", line_number);
                		exit(1);
        		}
		}
	}		
	else
	{
		while(!isOperator(c) && c != EOF && c != ')')
  		{
			if (c == '(')
  			{
				paren[0] = '(';
				return paren;
  			}
			if(tmp_pos > tmpSize){
                                tmpSize += 50;
                                token = (char*) checked_realloc(token, sizeof(char)*tmpSize);
                        }
			
			if (c == '\n') line_number++;
  			token[tmp_pos] = c;
  			tmp_pos++;
			c = get_next_byte(get_next_byte_argument);
			if(!isValid(c)){
                                fprintf(stderr, "%d: Invalid Syntax", line_number);
                                exit(1);
                        }
		}
	}
  	if(c == '\n'){
		line_number++;
	}
	if (c == ')') paren_number--;

	if (paren_number < 0)
	{
		fprintf(stderr, "%d: Invalid Syntax", line_number);
                exit(1);
	}
	if(!isValid(c)){
                fprintf(stderr, "%d: Invalid Syntax", line_number);
                exit(1);
        }
	 if(tmp_pos > tmpSize){
              tmpSize += 50;
              token = (char*) checked_realloc(token, sizeof(char)*tmpSize);
        }

  	token[tmp_pos] = c;
  	*pos = tmp_pos;
  	return token;
}
Exemplo n.º 27
0
void increase_token_size(command_stream_t s)
{
    s->token_size += 20;
    s->current_string = checked_realloc(s->current_string, sizeof(char*) * s->token_size);
}
Exemplo n.º 28
0
char*
get_executable_path (char* bin_name)
{
  if(bin_name == NULL)
    return NULL;

  // Check if this is a valid absolute price
  if (file_exists (bin_name))
    return bin_name;

  // First, find the current working directory
  char *cwd = getcwd (NULL, 0);

  // Does it exist relative to the current directory?
  char *path = checked_malloc (sizeof(char) * (strlen(cwd) + strlen(bin_name) + 1 + 1)); // Add one char for '/' and one for NULL
  strcpy (path, cwd);
  strcat (path, "/");
  strcat (path, bin_name);

  if (file_exists (path))
    return path;

  // If not, let's try the system PATH variable and see if we have any matches there
  char *syspath = getenv ("PATH");

  // "The application shall ensure that it does not modify the string pointed to by the getenv() function."
  // By definition of getenv, we copy the string and modify the copy with strtok
  char *syspath_copy = checked_malloc(sizeof (char) * (strlen (syspath) + 1 + 1)); // Add one char for '/' and one for NULL
  strcpy (syspath_copy, syspath);

  // Split the path
  char **path_elements = NULL;
  char *p = strtok (syspath_copy, ":");
  int path_items = 0, i;

  while (p)
  {
    path_elements = checked_realloc (path_elements, sizeof (char*) * (path_items + 2));
    path_elements[path_items] = p;

    path_items++;

    p = strtok (NULL, ":");
  }

  path_elements[path_items] = NULL; // Make sure the last item is null for later looping

  // Now, let's iterate over each item in the path and see if it's a fit
  for (i = 0; path_elements[i] != NULL; i++)
  {
    size_t len = sizeof(char) * (strlen(bin_name) + strlen(path_elements[i]) + 1);
    path = checked_grow_alloc (path, &len);
    strcpy (path, path_elements[i]);
    strcat (path, "/");
    strcat (path, bin_name);

    if (file_exists (path))
    {
      free (path_elements);
      free (syspath_copy);
      return path;
    }
  }

  free (path_elements);
  free (syspath_copy);
  free (path);
  return NULL; // If we got this far, there's an error.
}
Exemplo n.º 29
0
command_stream_t
make_command_stream (int (*get_next_byte) (void *),
                     void *get_next_byte_argument)
{
    
    //current character
    char curr;
    int tree_number = 1;
    char prev_char_stored = '\0';
    int consecutive_newlines = 0;
    
    
    //buffer size = 1KB
    int BUFFER_SIZE = 1024;
    //buffer to read characters into; buffer can hold 1024 chars at once
    char *buffer = (char *) checked_malloc(BUFFER_SIZE * sizeof(char));
    
    //int to count how many chars are in buffer
    int numChars = 0;
    
    //int to count which line we are on
    //int syntax_line_counter = 0;
    int invalid_char_line_counter = 1;
    
    //if this is true, we are searching for the right operand of an operator
    bool found_AND_OR_PIPE_SEQUENCE = false; //looking for operand
    
    
    //declare command stream and allocate space
    //maybe dont need to allocate space because initStream() already does?
    command_stream_t theStream;    // = (command_stream_t) checked_malloc(sizeof(struct command_stream));
    
    //initialize command_stream
    theStream = initStream();
    
    //start reading the chars from the input
    while ((curr = get_next_byte(get_next_byte_argument)) != EOF ) {
        
        if (numChars > 0){
            //only stores previous meaningful character, i.e. not whitespace
            if ((buffer[numChars-1] != ' ' && buffer[numChars-1] != '#')){
                prev_char_stored = buffer[numChars-1];
            }
        }
        
        if (prev_char_stored == '&' || prev_char_stored == '|' || prev_char_stored == ';'){
            found_AND_OR_PIPE_SEQUENCE = true;
        }
        
        
        
        ////////////////////////////////////////////////////////////
        //////////////////      NEWLINE CHAR    ////////////////////
        ////////////////////////////////////////////////////////////
        
        /*
         New variables introduced:
         char prev_char_stored;
         int consecutive_newlines;
         bool command_has_ended; //haven't needed to use yet
         
         */
        if (identify_char_type(curr) == NEWLINE_CHAR || identify_char_type(curr) == HASHTAG_CHAR){
            
            //found a newline, increment counter
            consecutive_newlines++;
            
            //hit second (or more) newline
            if (consecutive_newlines > 1){
                //not looking for an operator and
                if (!found_AND_OR_PIPE_SEQUENCE){
                    if (identify_char_type(curr) == NEWLINE_CHAR) {
                    //add second newline to buffer
                    buffer[numChars] = '\n';
                    numChars++;
                    curr = get_next_byte(get_next_byte_argument);
                    }
                    /*
                     check for newlines, whitespaces, and hashtags after second newline
                     Store newlines on the buffer, ignore white spaces, and for hashtags:
                     put hashtag and newline on the buffer
                     */
                    while (identify_char_type(curr) == NEWLINE_CHAR || identify_char_type(curr) == WHITESPACE_CHAR || identify_char_type(curr) == HASHTAG_CHAR){
                        if (curr == '\n'){
                            buffer[numChars] = '\n';
                            numChars++;
                        } else if (curr == '#'){
                            //add hashtag to buffer
                            consecutive_newlines++;
                            buffer[numChars] = '#';
                            numChars++;
                            
                            //go to end of comment
                            while (identify_char_type(curr) != NEWLINE_CHAR){
                                if ((curr = get_next_byte(get_next_byte_argument)) == EOF) {
                                    break;
                                }
                            }
                            //broke out of loop, curr is now a newline char; add to buffer
                            buffer[numChars] = '\n';
                            numChars++;
                            
                        }
                        
                        if ((curr = get_next_byte(get_next_byte_argument)) == EOF) {
                            break;
                        }
                    }
                    
                    consecutive_newlines = 0;
                    
                    //create temporary array with size of numChars;
                    char* buffer_no_whitespaces = checked_malloc(BUFFER_SIZE * (sizeof(char)));  //the correct syntaxed command
                    memset(buffer_no_whitespaces, '\0', BUFFER_SIZE * sizeof(char));
                    
                    //run validation, then parse if correct
                    
                    eatWhiteSpaces(buffer, numChars, buffer_no_whitespaces);
                    
                    
                    int pos = 0;
                    
                    while (buffer_no_whitespaces[pos] != '\0'){
                        if (identify_char_type(buffer_no_whitespaces[pos]) == NEWLINE_CHAR){
                            invalid_char_line_counter++;
                        }
                        if (identify_char_type(buffer_no_whitespaces[pos]) == INVALID_CHAR){
                            identify_char_type(buffer_no_whitespaces[pos]);
                            fprintf(stderr, "%d: Invalid character: %c <---", invalid_char_line_counter, buffer_no_whitespaces[pos]);
                            exit(1);
                        }
                        pos++;
                    }
                    
                    checkAndSyntax(buffer_no_whitespaces);
                    checkForConsecutiveTokens(buffer_no_whitespaces);
                    checkIfOperatorsHaveOperands(buffer_no_whitespaces);
                    validParentheses(buffer_no_whitespaces);
                    
                    /*
                     int i;
                     for (i= 0; i<numChars; i++){
                     printf("%c", buffer_no_whitespaces[i]);
                     }
                     
                     //this just separates commands
                     printf("\n");
                     */
                    
                    commandNode_t root = createNodeFromCommand(make_command_tree(buffer_no_whitespaces));
                    
                    //printf("adding command node to stream: %s\n", root->cmd->u.word[0]);
                    
                    write_list_t write_list = init_write_list();
                    
                    //printf("adding command node to stream: %s\n", root->cmd->u.word[0]);
                    root->write_list = make_write_list(write_list, root->cmd);
                    read_list_t read_list = init_read_list();
                    root->read_list = make_read_list(read_list, root->cmd);
                    
                    root->tree_number=tree_number;
                    
                    root->dependency_list = (commandNode_t*)(checked_realloc(root->dependency_list, (tree_number) * sizeof(commandNode_t)));
                    memset (root -> dependency_list, '\0', (tree_number) * sizeof(commandNode_t));
                    
                    
                    //printf("adding command node to stream: %s\n", root->cmd->u.word[0]);
                    
                    addNodeToStream(theStream, root);
                    
                    
                    //reset everything with memset
                    memset(buffer, '\0', BUFFER_SIZE * sizeof(char));
                    free(buffer_no_whitespaces);
                    numChars = 0;
                    consecutive_newlines = 0;
                    
                    tree_number++;
                    
                    
                    if (curr == EOF)
                        break;
                    /*
                     We are now at a new command.
                     Add first character to buffer, whether valid or invalid.
                     Will check syntax later.
                     */
                    if (identify_char_type(curr) != HASHTAG_CHAR){
                        buffer[numChars] = curr;
                        numChars++;
                    } else {
                        //add a hashtag and newline to the buffer
                        buffer[numChars] = '#';
                        numChars++;
                        
                        //get to the end of the line
                        while (identify_char_type(curr) != NEWLINE_CHAR){
                            if ((curr = get_next_byte(get_next_byte_argument)) == EOF) {
                                break;
                            }
                        }
                        
                        //now we have a newline; add newline to buffer
                        buffer[numChars]=curr;
                        numChars++;
                        consecutive_newlines++;
                    }
                    continue;
                } else { //if we are looking for operand, don't end the commmand
                    
                    while (identify_char_type(curr) == NEWLINE_CHAR || identify_char_type(curr) == WHITESPACE_CHAR || identify_char_type(curr) == HASHTAG_CHAR){
                        if (curr == '\n'){
                            buffer[numChars] = '\n';
                            numChars++;
                        } else if (curr == '#'){
                            //add hashtag to buffer
                            buffer[numChars] = '#';
                            numChars++;
                            
                            while (identify_char_type(curr) != NEWLINE_CHAR){
                                if ((curr = get_next_byte(get_next_byte_argument)) == EOF) {
                                    break;
                                }
                            }
                            //broke out of loop, curr is now a newline char; add to buffer
                            buffer[numChars] = '\n';
                            numChars++;
                        }
                        
                        if ((curr = get_next_byte(get_next_byte_argument)) == EOF) {
                            break;
                        }
                        
                        
                    }
                    //broken out of while loop, we now have a regular character; add to buffer
                    
                    if (curr == EOF)
                        break;
                    
                    buffer[numChars] = curr;
                    numChars++;
                    found_AND_OR_PIPE_SEQUENCE = false;
                    consecutive_newlines = 0;
                    continue;
                }
            } else {
                //add newline to buffer; this is when number of newlines equals one
                if (identify_char_type(curr) == HASHTAG_CHAR) {
                    buffer[numChars] = '#';
                    numChars++;
                    
                    while (identify_char_type(curr) != NEWLINE_CHAR){
                        if ((curr = get_next_byte(get_next_byte_argument)) == EOF) {
                            break;
                        }
                    }
                    
                }
                buffer[numChars] = '\n';
                numChars++;
                continue;
            }
        } //end newline case
        else {
            
            
            if (!found_AND_OR_PIPE_SEQUENCE && consecutive_newlines == 1) {
                buffer[numChars] = ';';
                numChars++;
            }
            
            buffer[numChars] = curr;
            numChars++;
            consecutive_newlines = 0;
            
            //if we are here we no longer skip lines
            found_AND_OR_PIPE_SEQUENCE = false;
        }
    }
    
    char* buffer_no_whitespaces = checked_malloc(BUFFER_SIZE * (sizeof(char)));  //the correct syntaxed command
    memset(buffer_no_whitespaces, '\0', BUFFER_SIZE * sizeof(char));
    
    //run validation, then parse if correct
    //void eatWhiteSpaces(char *buffer, int bufferSize, char *newArray)
    eatWhiteSpaces(buffer, numChars, buffer_no_whitespaces);
    int pos = 0;
    
    while (buffer_no_whitespaces[pos] != '\0'){
        if (identify_char_type(buffer_no_whitespaces[pos]) == NEWLINE_CHAR){
            invalid_char_line_counter++;
        }
        if (identify_char_type(buffer_no_whitespaces[pos]) == INVALID_CHAR){
            identify_char_type(buffer_no_whitespaces[pos]);
            fprintf(stderr, "%d: Invalid character: %c <---", invalid_char_line_counter, buffer_no_whitespaces[pos]);
            exit(1);
        }
        pos++;
    }
    
    checkAndSyntax(buffer_no_whitespaces);
    checkForConsecutiveTokens(buffer_no_whitespaces);
    checkIfOperatorsHaveOperands(buffer_no_whitespaces);
    validParentheses(buffer_no_whitespaces);
    
    /*
     if (buffer_no_whitespaces[0] != '\0') {
     int i;
     for (i= 0; i<numChars; i++){
     printf("%c", buffer_no_whitespaces[i]);
     }
     printf("\n");
     }*/
    
    
    //make sure buffer_no_whitespace is not empty
    if (buffer_no_whitespaces[0] != '\0') {
        commandNode_t root = createNodeFromCommand(make_command_tree(buffer_no_whitespaces));
        
        write_list_t write_list = init_write_list();
        root->write_list = make_write_list(write_list, root->cmd);
        read_list_t read_list = init_read_list();
        root->read_list = make_read_list(read_list, root->cmd);
        root->tree_number=tree_number;
        
        
        root->dependency_list = (commandNode_t*)(checked_realloc(root->dependency_list, (tree_number) * sizeof(commandNode_t)));
        memset (root -> dependency_list, '\0', (tree_number) * sizeof(commandNode_t));
        
        //printf("adding command node to stream: %s\n", root->cmd->u.word[0]);
        
        addNodeToStream(theStream, root);
    }
    
    free(buffer);
    free(buffer_no_whitespaces);
    
    theStream->blocked_commands = (commandNode_t*)checked_realloc(theStream->blocked_commands, theStream->num_nodes * sizeof(commandNode_t));
    memset(theStream->blocked_commands, '\0', theStream->num_nodes * sizeof(commandNode_t));
    
    return theStream;
}
Exemplo n.º 30
0
int
lexer(char* input, token** output, size_t* output_size)
{
  // this regex will tokenize the input
  regex_t r;
  regcomp(&r, "[A-Za-z0-9!%+,-/:@^_.]+|[|]{2}|[&]{2}|[\n;|()<>#]{1}",
      REG_EXTENDED);

  size_t used = 0;
  char** toks = (char**) checked_malloc(sizeof(char*) * strlen(input));
  regmatch_t m;
  size_t input_len = strlen(input);
  size_t i, j, k;
  int first_pass = 1;

  do
  {
    // delete leading whitespaces
    for (i = 0;
        input[i] == ' ' || input[i] == '\t' || (first_pass && input[i] == '\n');
        i++)
      ;
    input = memmove(input, input + i, input_len - i + 1);
    input_len -= i;

    if (first_pass)
      first_pass = 0;

    // exit if nothing left
    if (input_len == 0)
      break;

    // match the regex
    int matched = !regexec(&r, input, 1, &m, 0);

    // if no match and input not empty, it's a parse error
    if (!matched && input_len > 0)
      error(1, 0, "Syntax error.");

    // it's a parse error if we skip any characters
    if (m.rm_so != 0)
      error(1, 0, "Syntax error.");

    // store the match result
    size_t len = m.rm_eo - m.rm_so;
    char* f = (char*) malloc(len + 1);
    memcpy(f, input + m.rm_so, len);
    f[len] = 0;
    toks[used++] = f;

    // delete consumed input
    input = memmove(input, input + m.rm_eo, input_len - len + 1);
    input_len -= len;
  }
  while (input_len > 0);

  // assign types to the tokens
  *output = (token*) checked_malloc(sizeof(token) * used);

  int comment = 0;

  for (i = 0, j = 0; i < used; i++)
  {
    token_type type = UNKNOWN_TOKEN;
    char* t = toks[i];
    size_t len = strlen(t);
    if (len == 1)
    {
      char c = t[0];
      switch (c)
      {
      case ';':
        type = SEMICOLON_TOKEN;
        break;
      case '(':
        type = OPEN_PAREN_TOKEN;
        break;
      case ')':
        type = CLOSE_PAREN_TOKEN;
        break;
      case '|':
        type = PIPE_TOKEN;
        break;
      case '<':
        type = L_REDIR_TOKEN;
        break;
      case '>':
        type = R_REDIR_TOKEN;
        break;
      case '\n':
        type = NEWLINE_TOKEN;
        comment = 0;
        break;
      case '#':
        comment = 1;
        break;
      default:
        type = WORD_TOKEN;
        break;
      }
    }
    else if (len == 2)
    {
      if (!strcmp(t, "||"))
        type = OR_TOKEN;
      else if (!strcmp(t, "&&"))
        type = AND_TOKEN;
      else
      {
        type = WORD_TOKEN;
      }
    }
    else if (len > 2)
    {
      type = WORD_TOKEN;
    }
    else
    {
      error(1, 0, "invalid token");
      exit(1);
    }

    // drop all comment tokens, save the rest
    if (!comment)
    {
      (*output)[j].text = t;
      (*output)[j].type = type;
      j++;
    }
    else
    {
      free(t);
    }

    // debug
    /*char* type_names[11] = {"word", ";", "|", "&&", "||", "(", ")", "<", ">", "NL", "?"};
     if(!comment){
     if(t[0] != '\n')
     printf("%s\ttype: %s\n", t, type_names[type]);
     else
     printf("%s\n", "(NEWLINE)");
     }
     else
     printf("<!-- %s -->\n", t);*/
  }

  // delete meaningless newlines
  for (i = 0; i < j - 1; i++)
  {
    if ((*output)[i + 1].type == NEWLINE_TOKEN
        && ((*output)[i].type == SEMICOLON_TOKEN
            || (*output)[i].type == PIPE_TOKEN || (*output)[i].type == AND_TOKEN
            || (*output)[i].type == OR_TOKEN
            || (*output)[i].type == OPEN_PAREN_TOKEN
            || (*output)[i].type == CLOSE_PAREN_TOKEN
            || (*output)[i].type == NEWLINE_TOKEN))
    {
      free((*output)[i + 1].text);
      for (k = i + 2; k < j; k++)
      {
        (*output)[k - 1] = (*output)[k];
      }
      j--;
      i--;
    }
  }

  // delete trailing newline
  if ((*output)[j - 1].type == NEWLINE_TOKEN)
    j--;

  // delete leading newline
  if (j > 0 && (*output)[0].type == NEWLINE_TOKEN)
  {
    for (k = 1; k < j; k++)
    {
      (*output)[k - 1] = (*output)[k];
    }
    j--;
  }

  // shrink the array down to the proper size
  *output_size = j;
  *output = (token*) checked_realloc(*output, sizeof(token) * j);

  // clean up
  regfree(&r);
  free(toks);
  return 0;
}