visualtest/src/action_configparser.c
changeset 7924 fcb86d323770
equal deleted inserted replaced
7923:d9ecdf71effb 7924:fcb86d323770
       
     1 /* See COPYING.txt for the full license governing this code. */
       
     2 /**
       
     3  * \file action_configparser.c
       
     4  *
       
     5  * Source file for the parser for action config files.
       
     6  */
       
     7 
       
     8 #include <SDL_stdinc.h>
       
     9 #include <SDL_test.h>
       
    10 #include <string.h>
       
    11 #include "SDL_visualtest_action_configparser.h"
       
    12 #include "SDL_visualtest_rwhelper.h"
       
    13 #include "SDL_visualtest_parsehelper.h"
       
    14 
       
    15 static void
       
    16 FreeAction(SDLVisualTest_Action* action)
       
    17 {
       
    18     if(!action)
       
    19         return;
       
    20     switch(action->type)
       
    21     {
       
    22         case SDL_ACTION_LAUNCH:
       
    23         {
       
    24             char* path;
       
    25             char* args;
       
    26 
       
    27             path = action->extra.process.path;
       
    28             args = action->extra.process.args;
       
    29 
       
    30             if(path)
       
    31                 SDL_free(path);
       
    32             if(args)
       
    33                 SDL_free(args);
       
    34 
       
    35             action->extra.process.path = NULL;
       
    36             action->extra.process.args = NULL;
       
    37         }
       
    38         break;
       
    39     }
       
    40 }
       
    41 
       
    42 int
       
    43 SDLVisualTest_EnqueueAction(SDLVisualTest_ActionQueue* queue,
       
    44                             SDLVisualTest_Action action)
       
    45 {
       
    46     SDLVisualTest_ActionNode* node;
       
    47     if(!queue)
       
    48     {
       
    49         SDLTest_LogError("queue argument cannot be NULL");
       
    50         return 0;
       
    51     }
       
    52 
       
    53     node = (SDLVisualTest_ActionNode*)SDL_malloc(
       
    54                                       sizeof(SDLVisualTest_ActionNode));
       
    55     if(!node)
       
    56     {
       
    57         SDLTest_LogError("malloc() failed");
       
    58         return 0;
       
    59     }
       
    60     node->action = action;
       
    61     node->next = NULL;
       
    62     queue->size++;
       
    63     if(!queue->rear)
       
    64         queue->rear = queue->front = node;
       
    65     else
       
    66     {
       
    67         queue->rear->next = node;
       
    68         queue->rear = node;
       
    69     }
       
    70     return 1;
       
    71 }
       
    72 
       
    73 int
       
    74 SDLVisualTest_DequeueAction(SDLVisualTest_ActionQueue* queue)
       
    75 {
       
    76     SDLVisualTest_ActionNode* node;
       
    77     if(!queue)
       
    78     {
       
    79         SDLTest_LogError("queue argument cannot be NULL");
       
    80         return 0;
       
    81     }
       
    82     if(SDLVisualTest_IsActionQueueEmpty(queue))
       
    83     {
       
    84         SDLTest_LogError("cannot dequeue from empty queue");
       
    85         return 0;
       
    86     }
       
    87     if(queue->front == queue->rear)
       
    88     {
       
    89         FreeAction(&queue->front->action);
       
    90         SDL_free(queue->front);
       
    91         queue->front = queue->rear = NULL;
       
    92     }
       
    93     else
       
    94     {
       
    95         node = queue->front;
       
    96         queue->front = queue->front->next;
       
    97         FreeAction(&node->action);
       
    98         SDL_free(node);
       
    99     }
       
   100     queue->size--;
       
   101     return 1;
       
   102 }
       
   103 
       
   104 void
       
   105 SDLVisualTest_InitActionQueue(SDLVisualTest_ActionQueue* queue)
       
   106 {
       
   107     if(!queue)
       
   108     {
       
   109         SDLTest_LogError("queue argument cannot be NULL");
       
   110         return;
       
   111     }
       
   112     queue->front = NULL;
       
   113     queue->rear = NULL;
       
   114     queue->size = 0;
       
   115 }
       
   116 
       
   117 SDLVisualTest_Action*
       
   118 SDLVisualTest_GetQueueFront(SDLVisualTest_ActionQueue* queue)
       
   119 {
       
   120     if(!queue)
       
   121     {
       
   122         SDLTest_LogError("queue argument cannot be NULL");
       
   123         return NULL;
       
   124     }
       
   125     if(!queue->front)
       
   126     {
       
   127         SDLTest_LogError("cannot get front of empty queue");
       
   128         return NULL;
       
   129     }
       
   130 
       
   131     return &queue->front->action;
       
   132 }
       
   133 
       
   134 int
       
   135 SDLVisualTest_IsActionQueueEmpty(SDLVisualTest_ActionQueue* queue)
       
   136 {
       
   137     if(!queue)
       
   138     {
       
   139         SDLTest_LogError("queue argument cannot be NULL");
       
   140         return 1;
       
   141     }
       
   142 
       
   143     if(queue->size > 0)
       
   144         return 0;
       
   145     return 1;
       
   146 }
       
   147 
       
   148 void
       
   149 SDLVisualTest_EmptyActionQueue(SDLVisualTest_ActionQueue* queue)
       
   150 {
       
   151     if(queue)
       
   152     {
       
   153         while(!SDLVisualTest_IsActionQueueEmpty(queue))
       
   154             SDLVisualTest_DequeueAction(queue);
       
   155     }
       
   156 }
       
   157 
       
   158 /* Since the size of the queue is not likely to be larger than 100 elements
       
   159    we can get away with using insertion sort. */
       
   160 static void
       
   161 SortQueue(SDLVisualTest_ActionQueue* queue)
       
   162 {
       
   163     SDLVisualTest_ActionNode* head;
       
   164     SDLVisualTest_ActionNode* tail;
       
   165 
       
   166     if(!queue || SDLVisualTest_IsActionQueueEmpty(queue))
       
   167         return;
       
   168 
       
   169     head = queue->front;
       
   170     for(tail = head; tail && tail->next;)
       
   171     {
       
   172         SDLVisualTest_ActionNode* pos;
       
   173         SDLVisualTest_ActionNode* element = tail->next;
       
   174 
       
   175         if(element->action.time < head->action.time)
       
   176         {
       
   177             tail->next = tail->next->next;
       
   178             element->next = head;
       
   179             head = element;
       
   180         }
       
   181         else if(element->action.time >= tail->action.time)
       
   182         {
       
   183             tail = tail->next;
       
   184         }
       
   185         else
       
   186         {
       
   187             for(pos = head;
       
   188                 (pos->next->action.time < element->action.time);
       
   189                 pos = pos->next);
       
   190             tail->next = tail->next->next;
       
   191             element->next = pos->next;
       
   192             pos->next = element;
       
   193         }
       
   194     }
       
   195 
       
   196     queue->front = head;
       
   197     queue->rear = tail;
       
   198 }
       
   199 
       
   200 int
       
   201 SDLVisualTest_InsertIntoActionQueue(SDLVisualTest_ActionQueue* queue,
       
   202                                     SDLVisualTest_Action action)
       
   203 {
       
   204     SDLVisualTest_ActionNode* n;
       
   205     SDLVisualTest_ActionNode* prev;
       
   206     SDLVisualTest_ActionNode* newnode;
       
   207     if(!queue)
       
   208     {
       
   209         SDLTest_LogError("queue argument cannot be NULL");
       
   210         return 0;
       
   211     }
       
   212 
       
   213     if(SDLVisualTest_IsActionQueueEmpty(queue))
       
   214     {
       
   215         if(!SDLVisualTest_EnqueueAction(queue, action))
       
   216         {
       
   217             SDLTest_LogError("SDLVisualTest_EnqueueAction() failed");
       
   218             return 0;
       
   219         }
       
   220         return 1;
       
   221     }
       
   222 
       
   223     newnode = (SDLVisualTest_ActionNode*)malloc(sizeof(SDLVisualTest_ActionNode));
       
   224     if(!newnode)
       
   225     {
       
   226         SDLTest_LogError("malloc() failed");
       
   227         return 0;
       
   228     }
       
   229     newnode->action = action;
       
   230 
       
   231     queue->size++;
       
   232     for(n = queue->front, prev = NULL; n; n = n->next)
       
   233     {
       
   234         if(action.time < n->action.time)
       
   235         {
       
   236             if(prev)
       
   237             {
       
   238                 prev->next = newnode;
       
   239                 newnode->next = n;
       
   240             }
       
   241             else
       
   242             {
       
   243                 newnode->next = queue->front;
       
   244                 queue->front = newnode;
       
   245             }
       
   246             return 1;
       
   247         }
       
   248         prev = n;
       
   249     }
       
   250 
       
   251     queue->rear->next = newnode;
       
   252     newnode->next = NULL;
       
   253     queue->rear = newnode;
       
   254 
       
   255     return 1;
       
   256 }
       
   257 
       
   258 int
       
   259 SDLVisualTest_ParseActionConfig(char* file, SDLVisualTest_ActionQueue* queue)
       
   260 {
       
   261     char line[MAX_ACTION_LINE_LENGTH];
       
   262     SDLVisualTest_RWHelperBuffer buffer;
       
   263     char* token_ptr;
       
   264     int linenum;
       
   265     SDL_RWops* rw;
       
   266 
       
   267     if(!file)
       
   268     {
       
   269         SDLTest_LogError("file argument cannot be NULL");
       
   270         return 0;
       
   271     }
       
   272     if(!queue)
       
   273     {
       
   274         SDLTest_LogError("queue argument cannot be NULL");
       
   275         return 0;
       
   276     }
       
   277 
       
   278     rw = SDL_RWFromFile(file, "r");
       
   279     if(!rw)
       
   280     {
       
   281         SDLTest_LogError("SDL_RWFromFile() failed");
       
   282         return 0;
       
   283     }
       
   284 
       
   285     SDLVisualTest_RWHelperResetBuffer(&buffer);
       
   286     SDLVisualTest_InitActionQueue(queue);
       
   287     linenum = 0;
       
   288     while(SDLVisualTest_RWHelperReadLine(rw, line, MAX_ACTION_LINE_LENGTH,
       
   289                                          &buffer, '#'))
       
   290     {
       
   291         SDLVisualTest_Action action;
       
   292         int hr, min, sec;
       
   293 
       
   294         /* parse time */
       
   295         token_ptr = strtok(line, " ");
       
   296         if(!token_ptr ||
       
   297            (SDL_sscanf(token_ptr, "%d:%d:%d", &hr, &min, &sec) != 3))
       
   298         {
       
   299             SDLTest_LogError("Could not parse time token at line: %d",
       
   300                              linenum);
       
   301             SDLVisualTest_EmptyActionQueue(queue);
       
   302             SDL_RWclose(rw);
       
   303             return 0;
       
   304         }
       
   305         action.time = (((hr * 60 + min) * 60) + sec) * 1000;
       
   306 
       
   307         /* parse type */
       
   308         token_ptr = strtok(NULL, " ");
       
   309         if(SDL_strcasecmp(token_ptr, "launch") == 0)
       
   310             action.type = SDL_ACTION_LAUNCH;
       
   311         else if(SDL_strcasecmp(token_ptr, "kill") == 0)
       
   312             action.type = SDL_ACTION_KILL;
       
   313         else if(SDL_strcasecmp(token_ptr, "quit") == 0)
       
   314             action.type = SDL_ACTION_QUIT;
       
   315         else if(SDL_strcasecmp(token_ptr, "screenshot") == 0)
       
   316             action.type = SDL_ACTION_SCREENSHOT;
       
   317         else if(SDL_strcasecmp(token_ptr, "verify") == 0)
       
   318             action.type = SDL_ACTION_VERIFY;
       
   319         else
       
   320         {
       
   321             SDLTest_LogError("Could not parse type token at line: %d",
       
   322                              linenum);
       
   323             SDLVisualTest_EmptyActionQueue(queue);
       
   324             SDL_RWclose(rw);
       
   325             return 0;
       
   326         }
       
   327 
       
   328         /* parse the extra field */
       
   329         if(action.type == SDL_ACTION_LAUNCH)
       
   330         {
       
   331             int len;
       
   332             char* args;
       
   333             char* path;
       
   334             token_ptr = strtok(NULL, " ");
       
   335             len = token_ptr ? SDL_strlen(token_ptr) : 0;
       
   336             if(len <= 0)
       
   337             {
       
   338                 SDLTest_LogError("Please specify the process to launch at line: %d",
       
   339                                  linenum);
       
   340                 SDLVisualTest_EmptyActionQueue(queue);
       
   341                 SDL_RWclose(rw);
       
   342                 return 0;
       
   343             }
       
   344             path = (char*)SDL_malloc(sizeof(char) * (len + 1));
       
   345             if(!path)
       
   346             {
       
   347                 SDLTest_LogError("malloc() failed");
       
   348                 SDLVisualTest_EmptyActionQueue(queue);
       
   349                 SDL_RWclose(rw);
       
   350                 return 0;
       
   351             }
       
   352             SDL_strlcpy(path, token_ptr, len + 1);
       
   353 
       
   354             token_ptr = strtok(NULL, "");
       
   355             len = token_ptr ? SDL_strlen(token_ptr) : 0;
       
   356             if(len > 0)
       
   357             {
       
   358                 args = (char*)SDL_malloc(sizeof(char) * (len + 1));
       
   359                 if(!args)
       
   360                 {
       
   361                     SDLTest_LogError("malloc() failed");
       
   362                     SDL_free(path);
       
   363                     SDLVisualTest_EmptyActionQueue(queue);
       
   364                     SDL_RWclose(rw);
       
   365                     return 0;
       
   366                 }
       
   367                 SDL_strlcpy(args, token_ptr, len + 1);
       
   368             }
       
   369             else
       
   370                 args = NULL;
       
   371 
       
   372             action.extra.process.path = path;
       
   373             action.extra.process.args = args;
       
   374         }
       
   375 
       
   376         /* add the action to the queue */
       
   377         if(!SDLVisualTest_EnqueueAction(queue, action))
       
   378         {
       
   379             SDLTest_LogError("SDLVisualTest_EnqueueAction() failed");
       
   380             if(action.type == SDL_ACTION_LAUNCH)
       
   381             {
       
   382                 SDL_free(action.extra.process.path);
       
   383                 if(action.extra.process.args)
       
   384                     SDL_free(action.extra.process.args);
       
   385             }
       
   386             SDLVisualTest_EmptyActionQueue(queue);
       
   387             SDL_RWclose(rw);
       
   388             return 0;
       
   389         }
       
   390     }
       
   391     /* sort the queue of actions */
       
   392     SortQueue(queue);
       
   393 
       
   394     SDL_RWclose(rw);
       
   395     return 1;
       
   396 }