Example #1
0
static void performCommand(char *acLine, DynArray_T oHistoryList, 
                           char *pcProgName)

/* Expand any !commandprefix in acLine. Insert acLine into 
   oHistoryList iff the expanding succeeds and acLine does not consist
   of entirely whitespace characters. Lexically and syntactically 
   analyze acLine. Execute acLine if no errors are found. It is a 
   checked runtime error for acLine, oHistory, or pcProgName to be
   NULL. */

{
   char *pcTemp;
   Command_T oCommand;
   DynArray_T oTokens;
   int iSuccessful;

   assert(acLine != NULL);
   assert(oHistoryList != NULL);
   assert(pcProgName != NULL);

   if(histHasCommandPrefix(acLine))
   {
      iSuccessful = histExpandLine(acLine, oHistoryList, pcProgName);
      if(iSuccessful)
         printf("%s\n", acLine);
      else
         return;
   }
   oTokens = DynArray_new(0);
   iSuccessful = lexLine(acLine, oTokens, pcProgName);
   if(DynArray_getLength(oTokens) > 0)
   {
      /* Allocate memory to store command in oHistoryList iff 
         command does not consist of entirely whitespace
         characters. */
      pcTemp = (char*)malloc(strlen(acLine) + 1);
      assert(pcTemp != NULL);
      strcpy(pcTemp, acLine);
      DynArray_add(oHistoryList, pcTemp);

      if(iSuccessful)
      {
         oCommand = Command_new();
         iSuccessful = parseToken(oTokens, oCommand, pcProgName);
         if(iSuccessful)
            execute(oCommand, oHistoryList, pcProgName);
         Command_free(oCommand, NULL);
      }
   }
   DynArray_map(oTokens, Token_free, NULL);
   DynArray_free(oTokens);
}
Example #2
0
/**
 * test_DynArray_alloc
 * -----------------------------------------------------
 * Tests the functionality of DynArray_new() and
 * DynArray_free() functions.
 */
static int test_DynArray_alloc()
{
    printf("Testing DynArray_new(), DynArray_free(): ");
    int result = 1;
    DynArray_t* da = DynArray_new(10);
    
    result &= (da != NULL);
    result &= (da->length == 10);
    result &= (da->contents != NULL);

    DynArray_free(da);

    printf("%d\n", result);
    return result;
}
static DynArray_T lexLine(const char *pcLine)
{
   /* lexLine() uses a DFA approach.  It "reads" its characters from
      pcLine. The DFA has these three states: */
   enum LexState {STATE_START, STATE_IN_NUMBER, STATE_IN_WORD};

   /* The current state of the DFA. */
   enum LexState eState = STATE_START;

   /* An index into pcLine. */
   int iLineIndex = 0;

   /* Pointer to a buffer in which the characters comprising each
      token are accumulated. */
   char *pcBuffer;

   /* An index into the buffer. */
   int iBufferIndex = 0;

   char c;
   struct Token *psToken;
   DynArray_T oTokens;
   int iSuccessful;

   assert(pcLine != NULL);

   /* Create an empty token DynArray object. */
   oTokens = DynArray_new(0);
   if (oTokens == NULL)
      {perror(pcPgmName); exit(EXIT_FAILURE);}

   /* Allocate memory for a buffer that is large enough to store the
      largest token that might appear within pcLine. */
   pcBuffer = (char*)malloc(strlen(pcLine) + 1);
   if (pcBuffer == NULL)
      {perror(pcPgmName); exit(EXIT_FAILURE);}

   for (;;)
   {
      /* "Read" the next character from pcLine. */
      c = pcLine[iLineIndex++];

      switch (eState)
      {
         /* Handle the START state. */
         case STATE_START:
            if (c == '\0')
            {
               free(pcBuffer);
               return oTokens;
            }
            else if (isdigit(c))
            {
               pcBuffer[iBufferIndex++] = c;
               eState = STATE_IN_NUMBER;
            }
            else if (isalpha(c))
            {
               pcBuffer[iBufferIndex++] = c;
               eState = STATE_IN_WORD;
            }
            else if (isspace(c))
               eState = STATE_START;
            else
            {
               fprintf(stderr, "Invalid line\n");
               free(pcBuffer);
               freeTokens(oTokens);
               DynArray_free(oTokens);
               return NULL;
            }
            break;

         /* Handle the IN_NUMBER state. */
         case STATE_IN_NUMBER:
            if (c == '\0')
            {
               /* Create a NUMBER token. */
               pcBuffer[iBufferIndex] = '\0';
               psToken = newToken(TOKEN_NUMBER, pcBuffer);
               iSuccessful = DynArray_add(oTokens, psToken);
               if (! iSuccessful)
                  {perror(pcPgmName); exit(EXIT_FAILURE);}
               iBufferIndex = 0;
               free(pcBuffer);
               return oTokens;
            }
            else if (isdigit(c))
            {
               pcBuffer[iBufferIndex++] = c;
               eState = STATE_IN_NUMBER;
            }
            else if (isspace(c))
            {
               /* Create a NUMBER token. */
               pcBuffer[iBufferIndex] = '\0';
               psToken = newToken(TOKEN_NUMBER, pcBuffer);
               iSuccessful = DynArray_add(oTokens, psToken);
               if (! iSuccessful)
                  {perror(pcPgmName); exit(EXIT_FAILURE);}
               iBufferIndex = 0;
               eState = STATE_START;
            }
            else
            {
               fprintf(stderr, "Invalid line\n");
               free(pcBuffer);
               freeTokens(oTokens);
               DynArray_free(oTokens);
               return NULL;
            }
            break;

         /* Handle the IN_WORD state. */
         case STATE_IN_WORD:
            if (c == '\0')
            {
               /* Create a WORD token. */
               pcBuffer[iBufferIndex] = '\0';
               psToken = newToken(TOKEN_WORD, pcBuffer);
               iSuccessful = DynArray_add(oTokens, psToken);
               if (! iSuccessful)
                  {perror(pcPgmName); exit(EXIT_FAILURE);}
               iBufferIndex = 0;
               free(pcBuffer);
               return oTokens;
            }
            else if (isalpha(c))
            {
               pcBuffer[iBufferIndex++] = c;
               eState = STATE_IN_WORD;
            }
            else if (isspace(c))
            {
               /* Create a WORD token. */
               pcBuffer[iBufferIndex] = '\0';
               psToken = newToken(TOKEN_WORD, pcBuffer);
               iSuccessful = DynArray_add(oTokens, psToken);
               if (! iSuccessful)
                  {perror(pcPgmName); exit(EXIT_FAILURE);}
               iBufferIndex = 0;

               eState = STATE_START;
            }
            else
            {
               fprintf(stderr, "Invalid line\n");
               free(pcBuffer);
               freeTokens(oTokens);
               DynArray_free(oTokens);
               return NULL;
            }
            break;

         default:
            assert(0);
      }
   }
}
Command_T Command_new(char *pcName, DynArray_T oArgs, 
                      char *pcStdIn, char *pcStdOut) {
    int i;
    int argsLength; /* length of oArgs array */
    char* pcArg;
    size_t pcArgLength; /* track how much memory to give pcArg */
    Command_T oCommand;

    /* a command must have a name */
    assert(pcName != NULL);
    assert(oArgs != NULL);

    oCommand = (Command_T) malloc(sizeof(struct Command));
    if (oCommand == NULL) {
        fprintf(stderr, 
        "%s: Can't allocate memory for command\n", 
        pcPgmName); 
        exit(EXIT_FAILURE);
    }

    /* allocate memory for and set the command name */
    oCommand->pcName = (char*)malloc(strlen(pcName) + 1);
    if (oCommand->pcName == NULL) {
        fprintf(stderr, 
        "%s: Can't allocate memory for command\n", 
        pcPgmName); 
        exit(EXIT_FAILURE);
    }
    strcpy(oCommand->pcName, pcName);
    
    /* allocate memory for and set the command arguments*/
    argsLength = DynArray_getLength(oArgs);
    oCommand->oArgs = DynArray_new(0);
    for (i = 0; i < argsLength; i++) {
        pcArgLength = strlen((char*) DynArray_get(oArgs, i));
        pcArg = (char*) malloc(pcArgLength + 1);
        strcpy(pcArg, DynArray_get(oArgs, i));
        if (pcArg == NULL) {
            fprintf(stderr, 
            "%s: Can't allocate memory for command args\n", 
            pcPgmName); 
            exit(EXIT_FAILURE);
        }
        DynArray_add(oCommand->oArgs, pcArg);
    }

    /* allocate memory for and set the command stdin redirect */
    if (pcStdIn == NULL) {
        oCommand->pcStdIn = NULL;
    }
    else {
        oCommand->pcStdIn = (char*)malloc(strlen(pcStdIn) + 1);
        if (oCommand->pcStdIn == NULL) {
            fprintf(stderr, 
            "%s: Can't allocate memory for command\n", 
            pcPgmName); 
            exit(EXIT_FAILURE);
        }
        strcpy(oCommand->pcStdIn, pcStdIn);
    }   

    /* allocate memory for and set the command stdout redirect*/
    if (pcStdOut == NULL) {
        oCommand->pcStdOut = NULL;
    }
    else {
        oCommand->pcStdOut = (char*)malloc(strlen(pcStdOut) + 1);
        if (oCommand->pcStdOut == NULL) {
            fprintf(stderr, 
            "%s: Can't allocate memory for command\n", 
            pcPgmName); 
            exit(EXIT_FAILURE);
        }
        strcpy(oCommand->pcStdOut, pcStdOut);
    }
    return oCommand;

}
Example #5
0
int main(int argc, char *argv[])

/* Read lines from the .ishrc file residing in the HOME directory
   until EOF is reached. Write each line that is read to
   stdout and execute each line. Read a line from stdin and
   execute it. Repeat until EOF. Return 0. */

{
   char acLine[MAX_LINE_SIZE];
   char *pcTemp;
   DynArray_T oHistoryList; 
   FILE *psFile;
   int i;
   void (*pfRet)(int);

   pfRet = signal(SIGINT, SIG_IGN);
   if(pfRet == SIG_ERR) {perror(argv[0]); exit(EXIT_FAILURE); }

   oHistoryList = DynArray_new(0);

   pcTemp = getIshrc();
   psFile = fopen(pcTemp, "r");
   free(pcTemp);

   while (psFile != NULL && 
          fgets(acLine, MAX_LINE_SIZE, psFile) != NULL)
   {
      /* Remove '\n' if acLine ends with '\n'. This is done so 
         the commands in the history list do not end with '\n',
         which is necessary to properly expand !commandprefix. */
      if(acLine[strlen(acLine)-1] == '\n')
         acLine[strlen(acLine)-1] = '\0';
     
      printf("%% %s\n", acLine);
      /* Explicitly flush the stdout buffer so we can test ish
         properly by redirecting the output to a file. */
      fflush(stdout);
      
      performCommand(acLine, oHistoryList, argv[0]);
   }
   printf("%% ");
   fflush(stdout);
   while (fgets(acLine, MAX_LINE_SIZE, stdin) != NULL)
   {
      /* Remove '\n' if acLine ends with '\n'. This is done so 
         the commands in the history list do not end with '\n',
         which is necessary to properly expand !commandprefix. */
      if(acLine[strlen(acLine)-1] == '\n')
         acLine[strlen(acLine)-1] = '\0';
      
      performCommand(acLine, oHistoryList, argv[0]);

      printf("%% ");
      fflush(stdout);
   }
   printf("\n");
   fflush(stdout);

   for(i = 0; i < DynArray_getLength(oHistoryList); i++)
      free(DynArray_get(oHistoryList, i));
   DynArray_free(oHistoryList);
   return 0;
}