From 249b8fbd6e839ed85868b60a0e5ef0d65a57fdf3 Mon Sep 17 00:00:00 2001
From: John Hodge <tpg@ucc.gu.uwa.edu.au>
Date: Sat, 20 Nov 2010 15:47:58 +0800
Subject: [PATCH] Item file parsing :)

- Added --itemfile to change the item file from the default
- Used the POSIX regex library to parse the item file
- Random cleanups
---
 items.cfg           | 13 +++++++++
 itemsfile.txt       |  2 +-
 server/src/Makefile |  4 +--
 server/src/itemdb.c | 65 +++++++++++++++++++++++++++------------------
 server/src/main.c   | 14 ++++++++--
 server/src/server.c |  2 +-
 6 files changed, 68 insertions(+), 32 deletions(-)
 create mode 100644 items.cfg

diff --git a/items.cfg b/items.cfg
new file mode 100644
index 0000000..aa381cd
--- /dev/null
+++ b/items.cfg
@@ -0,0 +1,13 @@
+
+# Drinks
+drink	0	70	Lemonade
+drink	1	71	solo++
+drink	2	70	Solo
+drink	3	70	Orange Foo
+drink	4	255	V Black
+drink	5	101	Coke Zero
+drink	6	96	Coke
+
+# Pseudo items
+pseudo	0	128	clue	# clue.flac
+pseudo	0	10	laserprint	# print 10 pages
diff --git a/itemsfile.txt b/itemsfile.txt
index 69ee2d2..cbad61c 100644
--- a/itemsfile.txt
+++ b/itemsfile.txt
@@ -10,7 +10,7 @@ comments are allowed anywhere on a line and act until the end of the line.
 
 For example, a coke could be
 	drink	06	96	Coke
-A pseudo-item could le
+A pseudo-item could be
 	pseudo	01	10	Laserprint
 Or a snack
 	snack	64	128	Mars Bar
diff --git a/server/src/Makefile b/server/src/Makefile
index 3fee2f0..256ba42 100644
--- a/server/src/Makefile
+++ b/server/src/Makefile
@@ -5,9 +5,9 @@ OBJ := main.o server.o logging.o
 OBJ += dispense.o cokebank.o itemdb.o
 BIN := ../dispsrv
 
-LINKFLAGS := 
+LINKFLAGS := -g
 CPPFLAGS := 
-CFLAGS := -Wall
+CFLAGS := -Wall -g
 
 .PHONY: all clean
 
diff --git a/server/src/itemdb.c b/server/src/itemdb.c
index 01f801e..0ddcbf7 100644
--- a/server/src/itemdb.c
+++ b/server/src/itemdb.c
@@ -12,6 +12,7 @@
 #include <string.h>
 #include <ctype.h>
 #include "common.h"
+#include <regex.h>
 
 // === GLOBALS ===
  int	giNumItems = 0;
@@ -33,7 +34,22 @@ void Load_Itemlist(void)
 	char	buffer[BUFSIZ];
 	char	*line;
 	 int	lineNum = 0;
+	 int	i;
+	regex_t	regex;
+	regmatch_t	matches[5];
 	
+	i = regcomp(&regex, "^([a-zA-Z][a-zA-Z0-9]*)\\s+([0-9]+)\\s+([0-9]+)\\s+(.*)", REG_EXTENDED);
+	//i = regcomp(&regex, "\\(\\d+\\)", 0);//\\s+([0-9]+)\\s+([0-9]+)\\s+(.*)", 0);
+	if( i )
+	{
+		size_t	len = regerror(i, &regex, NULL, 0);
+		char	*errorStr = malloc(len);
+		regerror(i, &regex, errorStr, len);
+		fprintf(stderr, "Rexex compilation failed - %s\n", errorStr);
+		free(errorStr);
+		exit(-1);
+	}
+
 	// Error check
 	if(!fp) {
 		fprintf(stderr, "Unable to open item file '%s'\n", gsItemListFile);
@@ -43,8 +59,9 @@ void Load_Itemlist(void)
 	while( fgets(buffer, BUFSIZ, fp) )
 	{
 		char	*tmp;
-		char	*type, *num, *price, *desc;
-		
+		char	*type, *desc;
+		 int	num, price;
+
 		lineNum ++;
 
 		// Remove comments
@@ -56,31 +73,27 @@ void Load_Itemlist(void)
 		// Trim whitespace
 		line = trim(buffer);
 		
-		// Parse Line
-		// - Type
-		type = line;
-		// - Number
-		num = strchr(type, ' ');
-		if(num) {
-			while(*num == ' ' || *num == '\t')	num ++;
-		}
-		else {
-			fprintf(stderr, "Syntax error on line %i of item file\n", lineNum);
-			continue;
-		}
-		// - Price
-		price = strchr(num, ' ');
-		if( price ) {
-			while(*num == ' ' || *num == '\t')	num ++;
-		}
-		else {
-			fprintf(stderr, "Syntax error on line %i of item file\n", lineNum);
-			continue;
+		if(strlen(line) == 0)	continue;
+		
+		// Pass regex over line
+		if( (i = regexec(&regex, line, 5, matches, 0)) ) {
+			size_t  len = regerror(i, &regex, NULL, 0);
+			char    *errorStr = malloc(len);
+			regerror(i, &regex, errorStr, len);
+			fprintf(stderr, "Syntax error on line %i of item file '%s'\n%s", lineNum, gsItemListFile, errorStr);
+			free(errorStr);
+			exit(-1);
 		}
-		// - Name/Description
-		desc = strchr(price, ' ');
-	}
-	
+
+		// Read line data
+		type  = line + matches[1].rm_so;	line[ matches[1].rm_eo ] = '\0';
+		num   = atoi( line + matches[2].rm_so );
+		price = atoi( line + matches[3].rm_so );
+		desc  = line + matches[4].rm_so;
+		
+
+		printf("Item '%s' - %i cents, %s:%i\n", desc, price, type, num);
+	}	
 }
 
 char *trim(char *__str)
diff --git a/server/src/main.c b/server/src/main.c
index 969ac43..daf209f 100644
--- a/server/src/main.c
+++ b/server/src/main.c
@@ -9,13 +9,15 @@
  */
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 #include "common.h"
 
 // === IMPORTS ===
-extern void	Init_Cokebank(void);
+extern void	Init_Cokebank(void);	// cokebank.c
 extern void	Load_Itemlist(void);
 extern void	Server_Start(void);
 extern int	giServer_Port;
+extern char    *gsItemListFile;
 
 // === GLOBALS ===
  int	giDebugLevel = 0;
@@ -29,7 +31,7 @@ int main(int argc, char *argv[])
 	for( i = 1; i < argc; i++ )
 	{
 		char	*arg = argv[i];
-		if( arg[0] == '-' )
+		if( arg[0] == '-' && arg[1] != '-')
 		{
 			switch(arg[1])
 			{
@@ -44,6 +46,14 @@ int main(int argc, char *argv[])
 				break;
 			}
 		}
+		else if( arg[0] == '-' && arg[1] == '-' ) {
+			if( strcmp(arg, "--itemsfile") == 0 ) {
+				gsItemListFile = argv[++i];
+			}
+			else {
+				// Usage error?
+			}
+		}
 		else {
 			// Usage Error?
 		}
diff --git a/server/src/server.c b/server/src/server.c
index 7f0debb..6bf0434 100644
--- a/server/src/server.c
+++ b/server/src/server.c
@@ -241,7 +241,7 @@ char *Server_ParseClientCommand(tClient *Client, char *CommandString)
 			return gaServer_Commands[i].Function(Client, args);
 	}
 	
-	return strdup("400	Unknown Command\n");
+	return strdup("400 Unknown Command\n");
 }
 
 // ---
-- 
GitLab