Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <stdio.h>
- #include <ctype.h> /* isspace() */
- /* initial defines - pre-set limits. Subject to future changes.*/
- #define MAX_KEY_STRING_LEN 51 /* a 'key' can only be 50 chars long, not
- * including '[]'. This was chosen arbitrarily
- * to simplify programming and waste fewer CPU
- * cycles. '51' includes the null termination
- * byte.*/
- #define DEBUG 1
- /* global vars */
- FILE *fp; /* file pointer should be accessible anywhere in the parser */
- int pos = -1; /* position in file */
- char chr; /* value of current char in file, as grabbed by fgetc(). */
- char key[MAX_KEY_STRING_LEN]; /* char array containing key name being operated
- * on*/
- char *value; /* pointer to a string containing the value of a key in string
- * form */
- /*
- * current offset (position) in file. becomes zero the first time nextChar()
- * is called, and is added to on each subsequent call. This is here in case I
- * need to use fseek() at some point.
- */
- /* end of global vars */
- int nextChar() /* set chr to char and return 0 unless EOF reached, skip white
- * space */
- {
- chr = fgetc(fp);
- pos = pos + 1;
- /* keep going until we find non-whitespace. characters. */
- while ( isspace(chr) != 0 ) { /* isspace() returns non-zero for whitespace. */
- chr = fgetc(fp);
- pos = pos + 1;
- }
- if ( chr == EOF ) {
- return (4); /* End-Of-Transmission character */
- }
- return (0);
- }
- int openFile(char *filename) {
- /* open file (first arg) in read-only mode */
- fp=fopen(filename,"r");
- /* make sure file was readable */
- if(fp == NULL) {
- printf("Error reading file. Check permissions!\n");
- return (-1);
- }
- return (0);
- }
- int getKeyName() {
- int i = 0;
- /*
- * called to get a key name, when the next byte to be read from the file is
- * immediately proceeding a '['.
- */
- while ( (chr != ']') && (chr != EOF) && ( i < ( MAX_KEY_STRING_LEN ) ) ) {
- /* start grabbing chars */
- nextChar(fp);
- /* pos = pos + 1; */ /* nextChar() handles incrementing. Only needed if
- * using fgetc() directly. */
- key[i] = chr;
- i = i + 1;
- }
- if (chr == ']') {
- key[i - 1] = '\0'; /* replace ']' with null terminator. */
- return (0);
- }
- /* now catch things that go wrong */
- if ( chr == EOF ) {
- printf("Malformed save data! Reached end-of-file while looking for ']'\n");
- exit(EXIT_FAILURE);
- }
- if ( i == (MAX_KEY_STRING_LEN) ) {
- key[MAX_KEY_STRING_LEN - 1] = '\0'; /* force null termination */
- printf("Malformed save data!\n"
- "key name starting with '%s'\n"
- "is too long!\n"
- "(maximum length: %d characters)\n",key,MAX_KEY_STRING_LEN);
- exit(EXIT_FAILURE);
- }
- /* Error if we reached this point. Should be unreachable. */
- return (-1);
- } /* int getKeyName() */
- int parse(){
- /* first, check if item is an array. This is determined by if a curly brace
- * appears in text prior to a semicolon (if a semicolon is first, it is not
- * an array; just a value).
- */
- while ( (nextChar() == 0) ) { /* as long as we are able to read data */
- /* first we need a 'key,' which is enclosed in square brackets ([]), then we
- * need a 'value,' which is enclosed in double quote marks ("").
- */
- if (chr == '[') { /* get a new key name. */
- getKeyName(); /* this function sets 'key' to a string containing the key
- * value */
- #ifdef DEBUG
- printf("key name is %s\n",key);
- #endif
- /* done getting key name */
- } /* if(chr == '[') */
- if (chr == '=') { /* set key to value(s) within the next quote or '{' */
- /* first, seek for the special chars ( '{' and '"' ). */
- while( ( chr != '{' ) && ( chr != '"' ) && ( chr != EOF )) {
- nextChar();
- }
- /* now, we've found the value presumably.
- * the next byte we read will be the 1st char after the quote or '{'.
- * if it's a quote, we know the next value is part of the stored data
- * string. Otherwise, we have to do the same thing we just did to find
- * another key-value pair, separate from the first one.
- */
- if ( chr == '"' ) {
- /* once we have found quote marks, start getting the value within.
- * IT IS IMPORTANT TO NOT USE NEXTCHAR() FOR THIS PART, AS WITHIN THE
- * QUOTE MARKS, SPACES ARE IMPORTANT. */
- } /* if ( chr == '"' ) */
- } /* if (chr == '=') */
- } /* while ( (nextChar() == 0) ) */
- /* TODO */
- /* if nothing else is true, print a warning message,
- * and try again. If EOF is reached, error. */
- return 0;
- } /* int parse() */
- int main(int argc, char *argv[]) {
- /* make sure file name was given */
- if(argc <=1) { /* no arguments passed */
- printf("Error: No file argument was given.\n");
- exit(EXIT_FAILURE);
- }
- /* open file, exit if it goes wrong */
- if(openFile(argv[1]) != 0) {
- /* something went wrong opening the file; check in openFile() function */
- exit(EXIT_FAILURE);
- }
- else {
- /* we're golden. start parsing HERE. */
- return parse();
- }
- }
- int nextCharInclSpace() {/* basically a wrapper to fgetc(), but it also
- * increments where we are in the file. */
- /* also it does not return a char, but rather sets
- * 'chr'. Sorry if you hate it, it made more sense to
- * me because I'm an insane assembly programmer at
- * heart. Feel free to fix it, or I might later if
- * the urge strikes me.
- */
- chr = fgetc(fp);
- pos = pos + 1;
- if ( chr == EOF ) {
- return (4); /* End-Of-Transmission character */
- }
- return (0);
- }
- int getValString() {
- int i = 0;
- long int oldpos=ftell(fp); /* starting point to return to once we've
- * checked how long our string is.*/
- int len;
- /* first, find out how long the string is */
- while( (chr != '"') && (chr != EOF) ) {
- nextCharInclSpace();
- i = i + 1;
- }
- if(chr == '"') {
- len = i; /* not `i - 1` since the end quote will become a null terminator. */
- }
- /* now, set a value length to match */
- char val[len];
- /* seek back to where we were before doing this and this time read the value
- * into the buffer we've allocated */
- fseek(fp,oldpos,SEEK_SET);
- /* could also probably make it SEEK_CUR and move negative `i` places. */
- pos = pos - i;
- /* TODO - might need to move one further back sine 'i' starts at 0? */
- /* if there are bugs, this is one of the likely spots. */
- i=0;
- while (i<len) {
- val[i]=chr;
- nextCharInclSpace();
- i = i + 1;
- }
- val[len - 1] = '\0';
- #ifdef DEBUG
- printf("value name is %s\n",val);
- #endif
- /* now catch things that go wrong */
- if ( chr == EOF ) {
- printf("Malformed save data! Reached end-of-file while looking for ']'\n");
- exit(EXIT_FAILURE);
- }
- if ( i == (MAX_KEY_STRING_LEN) ) {
- key[MAX_KEY_STRING_LEN - 1] = '\0'; /* force null termination */
- printf("Malformed save data!\n"
- "key name starting with '%s'\n"
- "is too long!\n"
- "(maximum length: %d characters)\n",key,MAX_KEY_STRING_LEN);
- exit(EXIT_FAILURE);
- }
- if (chr == ']') {
- key[i] = '\0'; /* replace ']' with null terminator. */
- return (0);
- }
- /* Error if we reached this point. Should be unreachable. */
- return (-1);
- } /* int getValString() */
- /* internal memory structure:
- * the first item in any object struct is a string identifying it.
- *
- * the player can hold up to ten items, so the inventory array contains
- * ten item structs, and each item struct contains an item name and an item
- * quantity (a char array and an int).
- */
- /* this code just checks for hardcoded keys to start work on.
- * arrays/objects cannot be embedded in other arrays/objects to
- * simplify things for me. so for player->inventory, we do a separate
- * key called 'player.inventory'.*/
Advertisement
Add Comment
Please, Sign In to add comment