Snack handler added
[tpg/opendispense2.git] / src / server / itemdb.c
1 /*
2  * OpenDispense 2 
3  * UCC (University [of WA] Computer Club) Electronic Accounting System
4  *
5  * itemdb.c - Dispense Item Databse
6  *
7  * This file is licenced under the 3-clause BSD Licence. See the file COPYING
8  * for full details.
9  */
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <ctype.h>
14 #include "common.h"
15 #include <regex.h>
16
17 // === IMPORTS ===
18 extern tHandler gCoke_Handler;
19 extern tHandler gSnack_Handler;
20
21 // === PROTOTYPES ===
22 void    Load_Itemlist(void);
23 char    *trim(char *__str);
24
25 // === GLOBALS ===
26  int    giNumItems = 0;
27 tItem   *gaItems = NULL;
28 tHandler        gPseudo_Handler = {Name:"pseudo"};
29 tHandler        *gaHandlers[] = {&gPseudo_Handler, &gCoke_Handler, &gSnack_Handler};
30  int    giNumHandlers = sizeof(gaHandlers)/sizeof(gaHandlers[0]);
31 char    *gsItemListFile = DEFAULT_ITEM_FILE;
32
33 // === CODE ===
34 void Init_Handlers()
35 {
36          int    i;
37         for( i = 0; i < giNumHandlers; i ++ )
38         {
39                 if( gaHandlers[i]->Init )
40                         gaHandlers[i]->Init(0, NULL);   // TODO: Arguments
41         }
42 }
43
44 /**
45  * \brief Read the item list from disk
46  */
47 void Load_Itemlist(void)
48 {
49         FILE    *fp = fopen(gsItemListFile, "r");
50         char    buffer[BUFSIZ];
51         char    *line;
52          int    lineNum = 0;
53          int    i;
54         regex_t regex;
55         regmatch_t      matches[5];
56         
57         i = regcomp(&regex, "^([a-zA-Z][a-zA-Z0-9]*)\\s+([0-9]+)\\s+([0-9]+)\\s+(.*)", REG_EXTENDED);
58         if( i )
59         {
60                 size_t  len = regerror(i, &regex, NULL, 0);
61                 char    *errorStr = malloc(len);
62                 regerror(i, &regex, errorStr, len);
63                 fprintf(stderr, "Rexex compilation failed - %s\n", errorStr);
64                 free(errorStr);
65                 exit(-1);
66         }
67
68         // Error check
69         if(!fp) {
70                 fprintf(stderr, "Unable to open item file '%s'\n", gsItemListFile);
71                 perror("Unable to open item file");
72         }
73         
74         while( fgets(buffer, BUFSIZ, fp) )
75         {
76                 char    *tmp;
77                 char    *type, *desc;
78                  int    num, price;
79                 tHandler        *handler;
80
81                 lineNum ++;
82
83                 // Remove comments
84                 tmp = strchr(buffer, '#');
85                 if(tmp) *tmp = '\0';
86                 tmp = strchr(buffer, ';');
87                 if(tmp) *tmp = '\0';
88                 
89                 // Trim whitespace
90                 line = trim(buffer);
91                 
92                 if(strlen(line) == 0)   continue;
93                 
94                 // Pass regex over line
95                 if( (i = regexec(&regex, line, 5, matches, 0)) ) {
96                         size_t  len = regerror(i, &regex, NULL, 0);
97                         char    *errorStr = malloc(len);
98                         regerror(i, &regex, errorStr, len);
99                         fprintf(stderr, "Syntax error on line %i of item file '%s'\n%s", lineNum, gsItemListFile, errorStr);
100                         free(errorStr);
101                         exit(-1);
102                 }
103
104                 // Read line data
105                 type  = line + matches[1].rm_so;        line[ matches[1].rm_eo ] = '\0';
106                 num   = atoi( line + matches[2].rm_so );
107                 price = atoi( line + matches[3].rm_so );
108                 desc  = line + matches[4].rm_so;        
109
110                 printf("Item '%s' - %i cents, %s:%i\n", desc, price, type, num);
111
112                 handler = NULL;
113                 for( i = 0; i < giNumHandlers; i ++ )
114                 {
115                         if( strcmp(type, gaHandlers[i]->Name) == 0 ) {
116                                 handler = gaHandlers[i];
117                                 break;
118                         }
119                 }
120
121                 if( !handler ) {
122                         fprintf(stderr, "Unknow item type '%s' on line %i (%s)\n", type, lineNum, desc);
123                         continue ;
124                 }
125
126                 for( i = 0; i < giNumItems; i ++ )
127                 {
128                         if( gaItems[i].Handler != handler )     continue;
129                         if( gaItems[i].ID != num )      continue;
130
131                         printf("Redefinition of %s:%i, updated\n", handler->Name, num);
132                         gaItems[i].Price = price;
133                         free(gaItems[i].Name);
134                         gaItems[i].Name = strdup(desc);
135                         break;
136                 }
137                 if( i < giNumItems )    continue;
138
139                 gaItems = realloc( gaItems, (giNumItems + 1)*sizeof(gaItems[0]) );
140                 gaItems[giNumItems].Handler = handler;
141                 gaItems[giNumItems].ID = num;
142                 gaItems[giNumItems].Price = price;
143                 gaItems[giNumItems].Name = strdup(desc);
144                 giNumItems ++;
145         }       
146 }
147
148 char *trim(char *__str)
149 {
150         char    *ret;
151          int    i;
152         
153         while( isspace(*__str) )
154                 __str++;
155         ret = __str;
156
157         i = strlen(ret);
158         while( i-- && isspace(__str[i]) ) {
159                 __str[i] = '\0';
160         }
161
162         return ret;
163 }

UCC git Repository :: git.ucc.asn.au