Subversion Repositories shark

Rev

Rev 1208 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include <kernel/kern.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "parser.h"

//#define PARSER_DEBUG

static int find_break(char **buf, int find_type, struct timespec *time, int *val)
{

  int i;
  char str[20];

  i = 0;
  while (((char *)(*buf))[i] == ' ' || ((char *)(*buf))[i] == ':' ||
         ((char *)(*buf))[i] == '\n' || ((char *)(*buf))[i] == '\r') i++;
  *buf += i;

  if (!strncmp(*buf,"END",3) && find_type == PAR_NOTHING) {
    *buf += 5;
    return PAR_END;
  }
 
  i = 0;
  if (((char *)(*buf))[0] == '#' && find_type == PAR_NOTHING) {
    while (((char *)(*buf))[i] != '\n' && ((char *)(*buf))[i] != '\r') i++;
    *buf += i;
    return PAR_FOUND;
  }

  switch (find_type) {
 
    case PAR_NOTHING:
      if (((char *)(*buf))[0] == ';' ||
          ((char *)(*buf))[0] < 32) {
            *buf += 1;
            return PAR_FOUND;
          }
      break;

    case PAR_TOTAL_EXEC_TIME:
      if (!strncmp(*buf, "TOTAL_EXEC_TIME:",16)) {
        *buf += 16;
        return PAR_FOUND;
      }
      break;
   
    case PAR_TIME:
      if (((char *)(*buf))[0] != '[') return PAR_ERROR;
      *buf += 1;
      i = 0;
      while (((char *)(*buf))[i] >= '0' && ((char *)(*buf))[i] <= '9') {
        str[i] = ((char *)(*buf))[i];
        i++;
      }
      if (((char *)(*buf))[i] != ']') return PAR_ERROR;
      str[i] = 0;
      time->tv_sec = atoi(str);
      i += 2;
      *buf += i;
      i = 0;
      while (((char *)(*buf))[i] >= '0' && ((char *)(*buf))[i] <= '9') {
        str[i] = ((char *)(*buf))[i];
        i++;
      }
      if (((char *)(*buf))[i] != ']') return PAR_ERROR;
      str[i] = 0;
      time->tv_nsec = atoi(str) * 1000;
      i += 2;
      *buf += i;
      return PAR_FOUND;
      break;

    case PAR_TASK_TYPE:
      if (!strncmp(*buf, "NRT:",4)) {
        *val = PAR_TASK_NRT;
        *buf += 4;
        return PAR_FOUND;
      }
      if (!strncmp(*buf, "HARD:",5)) {
        *val = PAR_TASK_HARD;
        *buf += 5;
        return PAR_FOUND;
      }
      if (!strncmp(*buf, "SOFT:",5)) {
        *val = PAR_TASK_SOFT;
        *buf += 5;
        return PAR_FOUND;
      }
      if (!strncmp(*buf, "BACK:",5)) {
        *val = PAR_TASK_BACK;
        *buf += 5;
        return PAR_FOUND;
      }
      if (!strncmp(*buf, "FSF:",4)) {
        *val = PAR_TASK_FSF;
        *buf += 4;
        return PAR_FOUND;
      }
      break;

   case PAR_TASK_NUMBER:
      if (((char *)(*buf))[0] != '[') return PAR_ERROR;
      *buf += 1;
      i = 0;
      while (((char *)(*buf))[i] >= '0' && ((char *)(*buf))[i] <= '9') {
        str[i] = ((char *)(*buf))[i];
        i++;
      }
      if (((char *)(*buf))[i] != ']') return PAR_ERROR;
      str[i] = 0;
      *val = atoi(str);
      i += 2;
      *buf += i;
      return PAR_FOUND;
      break;

    case PAR_LOCAL_SCHEDULER:
      if (!strncmp(*buf,"POSIX",5)) {
        *buf += 5;
        *val = PAR_POSIX;
        return PAR_FOUND;
      }
      if (!strncmp(*buf,"EDF",3)) {
        *buf += 3;
        *val = PAR_EDF;
        return PAR_FOUND;
      }
      if (!strncmp(*buf,"RM",2)) {
        *buf += 2;
        *val = PAR_RM;
        return PAR_FOUND;
      }
      break;
   
    case PAR_ACT_TYPE:
      if (!strncmp(*buf,"ACT_SINGLE(",11)) {
        *buf += 11;
        *val = PAR_ACT_SINGLE;
        return PAR_FOUND;
      }
      if (!strncmp(*buf,"ACT_PERIODIC(",13)) {
        *buf += 13;
        *val = PAR_ACT_PERIODIC;
        return PAR_FOUND;
      }
      if (!strncmp(*buf,"ACT_MEAN(",9)) {
        *buf += 9;
        *val = PAR_ACT_MEAN;
        return PAR_FOUND;
      }
      if (!strncmp(*buf,"ACT_GAUSS(",10)) {
        *buf += 10;
        *val = PAR_ACT_GAUSS;
        return PAR_FOUND;;
      }
      if (!strncmp(*buf,"ACT_GAUSS_MAX(",14)) {
        *buf += 14;
        *val = PAR_ACT_GAUSS_MAX;
        return PAR_FOUND;
      }
      return PAR_ERROR;
      break;

   case PAR_EXEC_TYPE:
     if (!strncmp(*buf,"EXEC_CONST(",11)) {
       *buf += 11;
       *val = PAR_EXEC_CONST;
       return PAR_FOUND;
     }
     if (!strncmp(*buf,"EXEC_MEAN(",10)) {
       *buf += 10;
       *val = PAR_EXEC_MEAN;
       return PAR_FOUND;
     }
     if (!strncmp(*buf,"EXEC_GAUSS(",11)) {
       *buf += 11;
       *val = PAR_EXEC_GAUSS;
       return PAR_FOUND;
     }
     if (!strncmp(*buf,"EXEC_GAUSS_MAX(",15)) {
       *buf += 15;
       *val = PAR_EXEC_GAUSS_MAX;
       return PAR_FOUND;
     }
     return PAR_ERROR;
     break;

   case PAR_CRIT_SESSION:
     if (!strncmp(*buf,"NO_CRIT",7)) {
       *buf += 7;
       *val = PAR_NO_CRIT;
       return PAR_FOUND;
     }
     if (!strncmp(*buf,"CRIT(",5)) {
       *buf += 5;
       *val = PAR_CRIT;
       return PAR_FOUND;
     }
     return PAR_ERROR;
     break;  

   case PAR_FSF_SERVER:
     if (!strncmp(*buf,"[S",2)) {
       *buf += 2;
       i = 0;
       while (((char *)(*buf))[i] >= '0' && ((char *)(*buf))[i] <= '9') {
          str[i] = ((char *)(*buf))[i];
          i++;
       }
       if (((char *)(*buf))[i] != ']') return PAR_ERROR;
       str[i] = 0;
       *val = atoi(str);
       i += 2;
       *buf += i;
       return PAR_FOUND;
     } else return PAR_ERROR;
     break;

   }

   return PAR_ERROR;

}

void par_error(int line_num)
{

  cprintf("\nParser error: line [%d]\n",line_num);
  sys_end();

}

/* result:
 * 0 -> nothing
 * 1 -> total
 * 2 -> new task-loader
 * 3 -> end file
 */

int line_parser(char **pbuf, int line_num, struct timespec *total, struct loader_task **last)
{
  struct timespec time;
  struct loader_task *ld = NULL;
  int val, res;

  res = find_break(pbuf, PAR_NOTHING, &time, &val);
  if (res == PAR_FOUND) return 0;
  if (res == PAR_END) return 3;

  res = find_break(pbuf,PAR_TOTAL_EXEC_TIME, &time, &val);
  if (res == PAR_FOUND) {
    NULL_TIMESPEC(total);
    res = find_break(pbuf, PAR_TIME, &time, &val);
    if (res == PAR_FOUND) {
      TIMESPEC_ASSIGN(total,&time);
      #ifdef PARSER_DEBUG
        cprintf("TOTAL EXEC TIME SEC = %ld NSEC = %ld\n",total->tv_sec,total->tv_nsec);
      #endif
      return 1;
    } else par_error(line_num);
  }

  res = find_break(pbuf,PAR_TASK_TYPE, &time, &val);
  if (res == PAR_FOUND) {
    #ifdef PARSER_DEBUG
      cprintf("TASK TYPE = %d\n",val);
    #endif

    ld = malloc(sizeof(struct loader_task));
    if (ld == NULL) par_error(line_num);
 
    ld->next = NULL;
    *last = ld;
 
    ld->task_type = val;

  } else par_error(line_num);

  if (ld->task_type == PAR_TASK_FSF) {
    res = find_break(pbuf,PAR_FSF_SERVER, &time, &val);
    if (res == PAR_FOUND) {
      #ifdef PARSER_DEBUG
        cprintf("TASK SERVER = %d\n",val);
      #endif
                                                                                                                             
      ld->server = val;
    } else par_error(line_num);

    res = find_break(pbuf,PAR_LOCAL_SCHEDULER, &time, &val);
    if (res == PAR_FOUND) {
      #ifdef PARSER_DEBUG
        cprintf("TASK LOCAL SCHEDULER = %d\n",val);
      #endif
                                                                                                                             
      ld->local_scheduler = val;
    } else par_error(line_num);
                                                                                                                             
  } else {
    res = find_break(pbuf,PAR_TASK_NUMBER, &time, &val);
    if (res == PAR_FOUND) {
      #ifdef PARSER_DEBUG
        cprintf("TASK LEVEL = %d\n",val);
      #endif

      ld->task_level = val;

    } else par_error(line_num);
  }

  res = find_break(pbuf,PAR_TASK_NUMBER, &time, &val);
  if (res == PAR_FOUND) {
    #ifdef PARSER_DEBUG
      cprintf("TASK NUMBER = %d\n",val);
    #endif

    ld->number = val;

  } else par_error(line_num);

  res = find_break(pbuf,PAR_ACT_TYPE, &time, &val);
  if (res == PAR_FOUND) {
    #ifdef PARSER_DEBUG
      cprintf("ACTIVATION TYPE: %d (",val);
    #endif

    ld->act_type = val;
   
    res = find_break(pbuf,PAR_TIME, &time, &val);
    if (res == PAR_FOUND) {
      #ifdef PARSER_DEBUG
        cprintf("[%ld][%ld]",time.tv_sec,time.tv_nsec/1000);
      #endif
      TIMESPEC_ASSIGN(&ld->act_par_1,&time);
    } else par_error(line_num);

    if (ld->act_type != PAR_ACT_SINGLE) {
      res = find_break(pbuf,PAR_TIME, &time, &val);
      if (res == PAR_FOUND) {
        #ifdef PARSER_DEBUG
          cprintf(",[%ld][%ld]",time.tv_sec,time.tv_nsec/1000);
        #endif
        TIMESPEC_ASSIGN(&ld->act_par_2,&time);
        } else par_error(line_num);
    }

    if (ld->act_type != PAR_ACT_SINGLE && ld->act_type != PAR_ACT_PERIODIC) {
      res = find_break(pbuf,PAR_TIME, &time, &val);
      if (res == PAR_FOUND) {
        #ifdef PARSER_DEBUG
          cprintf(",[%ld][%ld]",time.tv_sec,time.tv_nsec/1000);
        #endif
        TIMESPEC_ASSIGN(&ld->act_par_3,&time);
        } else par_error(line_num);
    }

    if (ld->act_type != PAR_ACT_SINGLE && ld->act_type != PAR_ACT_PERIODIC &&
        ld->act_type != PAR_ACT_MEAN && ld->act_type != PAR_ACT_GAUSS) {
      res = find_break(pbuf,PAR_TIME, &time, &val);
      if (res == PAR_FOUND) {
        #ifdef PARSER_DEBUG
          cprintf(",[%ld][%ld]",time.tv_sec,time.tv_nsec/1000);
        #endif
        TIMESPEC_ASSIGN(&ld->act_par_4,&time);
        } else par_error(line_num);
    }

    #ifdef PARSER_DEBUG
      cprintf(")\n");
    #endif

  } else par_error(line_num);

  res = find_break(pbuf,PAR_TIME, &time, &val);
  if (res == PAR_FOUND) {
    #ifdef PARSER_DEBUG
      cprintf("DEADLINE: [%ld][%ld]\n",time.tv_sec,time.tv_nsec/1000);
    #endif
    TIMESPEC_ASSIGN(&ld->deadline,&time);
  } else par_error(line_num);

  res = find_break(pbuf,PAR_TIME, &time, &val);
  if (res == PAR_FOUND) {
    #ifdef PARSER_DEBUG
      cprintf("WCET: [%ld][%ld]\n",time.tv_sec,time.tv_nsec/1000);
    #endif
    TIMESPEC_ASSIGN(&ld->wcet,&time);
  } else par_error(line_num);

  res = find_break(pbuf,PAR_EXEC_TYPE, &time, &val);
  if (res == PAR_FOUND) {
    #ifdef PARSER_DEBUG
      cprintf("EXEC TYPE: %d (",val);
    #endif
    ld->exec_type = val;
    res = find_break(pbuf,PAR_TIME, &time, &val);
    if (res == PAR_FOUND) {
      #ifdef PARSER_DEBUG
        cprintf("[%ld][%ld]",time.tv_sec,time.tv_nsec/1000);
      #endif
      TIMESPEC_ASSIGN(&ld->exec_par_1,&time);
    } else par_error(line_num);
                                                                                                                             
    if (ld->exec_type != PAR_EXEC_CONST) {
      res = find_break(pbuf,PAR_TIME, &time, &val);
      if (res == PAR_FOUND) {
        #ifdef PARSER_DEBUG
          cprintf(",[%ld][%ld]",time.tv_sec,time.tv_nsec/1000);
        #endif
        TIMESPEC_ASSIGN(&ld->exec_par_2,&time);
        } else par_error(line_num);
    }
                                                                                                                             
    if (ld->exec_type != PAR_EXEC_CONST && ld->exec_type != PAR_EXEC_MEAN &&
        ld->exec_type != PAR_EXEC_GAUSS) {
      res = find_break(pbuf,PAR_TIME, &time, &val);
      if (res == PAR_FOUND) {
        #ifdef PARSER_DEBUG
          cprintf(",[%ld][%ld]",time.tv_sec,time.tv_nsec/1000);
        #endif
        TIMESPEC_ASSIGN(&ld->exec_par_3,&time);
        } else par_error(line_num);
    }
                                                                                                                             
    #ifdef PARSER_DEBUG
      cprintf(")\n");
    #endif

  } else par_error(line_num);

  res = find_break(pbuf,PAR_CRIT_SESSION, &time, &val);
  if (res == PAR_FOUND) {
    #ifdef PARSER_DEBUG
      cprintf("CRITITCAL SESSION: %d (",val);
    #endif
    ld->crit_type = val;
    if (ld->crit_type == PAR_CRIT) {
      res = find_break(pbuf,PAR_TASK_NUMBER, &time, &val);
      if (res == PAR_FOUND) {
        #ifdef PARSER_DEBUG
          cprintf("[%d]",val);
        #endif
        ld->resource = val;
      } else par_error(line_num);
      res = find_break(pbuf,PAR_TIME, &time, &val);
      if (res == PAR_FOUND) {
        #ifdef PARSER_DEBUG
          cprintf(",[%ld][%ld]",time.tv_sec,time.tv_nsec/1000);
        #endif
        TIMESPEC_ASSIGN(&ld->crit_par_1,&time);
      } else par_error(line_num);
      res = find_break(pbuf,PAR_TIME, &time, &val);
      if (res == PAR_FOUND) {
        #ifdef PARSER_DEBUG
          cprintf(",[%ld][%ld]",time.tv_sec,time.tv_nsec/1000);
        #endif
        TIMESPEC_ASSIGN(&ld->crit_par_2,&time);
      } else par_error(line_num);
      res = find_break(pbuf,PAR_TIME, &time, &val);
      if (res == PAR_FOUND) {
        #ifdef PARSER_DEBUG
          cprintf(",[%ld][%ld]",time.tv_sec,time.tv_nsec/1000);
        #endif
        TIMESPEC_ASSIGN(&ld->crit_par_3,&time);
      } else par_error(line_num);
      res = find_break(pbuf,PAR_TIME, &time, &val);
      if (res == PAR_FOUND) {
        #ifdef PARSER_DEBUG
          cprintf(",[%ld][%ld]",time.tv_sec,time.tv_nsec/1000);
        #endif
        TIMESPEC_ASSIGN(&ld->crit_par_4,&time);
      } else par_error(line_num);

    }
   
    #ifdef PARSER_DEBUG
      cprintf(")\n");
    #endif
                                                                                                                             
  } else par_error(line_num);

  return 2;

}