sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

action_configparser.c (10173B)


      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 }