/***************************************************************************/ /* Killer List Of Video-games Database. */ /* Copyright (C) 1993 John Keay */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* This program is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with this program; if not, write to the Free Software */ /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* */ /* For more details see 'COPYING' */ /* John Keay (keay@tiuk.ti.com) */ /***************************************************************************/ #include #include #include #include #include "proto.h" #include "parse.h" #include "game.h" #include "klovdb.h" /* Not all libraries contain the strncasecmp function so I've added my own. */ /* This implementation only returns equal/not equal information */ /* unlike the real strncasecmp */ int my_strncasecmp(s1,s2,n) char *s1; char *s2; unsigned n; { while(n && *s1 && *s2) { if(tolower(*s1) != tolower(*s2)) return(1); s1++; s2++; n--; } if(!n) return(0); /* all characters matched */ if(!*s1 && !*s2) return(0); /* both strings ended together */ return(1); /* one string ended before the other */ } condition_t get_condition(s) char *s; { condition_t c = CND_NONE; if(s) { while(*s && *s != '<' && *s != '>' && *s != '!' && *s != '=') s++; if(*s == '<') { if(s[1] == '=') return(CND_LE); if(s[1] == '>') return(CND_NE); return(CND_LT); } else if(*s == '>') { if(s[1] == '=') return(CND_GE); return(CND_GT); } else if(*s == '!') { return(CND_NE); } else if(*s == '=') { if(s[1] == '>') return(CND_GE); return(CND_EQ); } } return(c); } int find_number(s) char *s; { int n = -1; if(s) { while(*s && !isdigit(*s)) s++; if(*s) n = atoi(s); } return(n); } int my_compare(s,k) char *s; char *k; { condition_t cond; int n1,n2; if(!k) return(1); /* Not interested in this field */ if(!s) return(0); /* No string to compare to */ cond = get_condition(k); n1 = find_number(s); n2 = find_number(k); if(cond != CND_NONE && n1 != -1 && n2 != -1) { if(n1 != -1 && n2 != -1) { switch (cond) { case CND_EQ: return(n1 == n2); case CND_NE: return(n1 != n2); case CND_LT: return(n1 < n2); case CND_LE: return(n1 <= n2); case CND_GT: return(n1 > n2); case CND_GE: return(n1 >= n2); case CND_NONE: break; } } } else { int len = strlen(k); for(;*s;s++) if(!my_strncasecmp(s,k,len)) return(1); } return(0); } void list_matches(l,k,fp,fn) list_ptr l; game_ptr k; FILE *fp; print_fn fn; { game_ptr g; int num_match = 0; int num = 0; if(!l) return; for(g=l->head;g;g=g->next) { int match = 1; num++; if(!my_compare(g->name,k->name)) match = 0; else if(!my_compare(g->date,k->date)) match = 0; else if(!my_compare(g->company,k->company)) match = 0; else if(k->flags && (g->flags & k->flags) != k->flags) match = 0; else if(!my_compare(g->produced,k->produced)) match = 0; else if(!my_compare(g->players,k->players)) match = 0; else if(!my_compare(g->text,k->text)) match = 0; if(match) { num_match++; (*fn)(g,fp); } } fprintf(fp,"[ %4d game%s checked %4d match%s ]\n", num,((num==1)?" ":"s"), num_match,((num_match==1)?" ":"es")); } void prompt(p,s,fp) char *p; char *s; FILE *fp; { int ch; fprintf(stdout,"%s",p); ch = fgetc(fp); while(ch != '\n') { *s++ = ch; ch = fgetc(fp); } *s = '\0'; } game_ptr get_search_key(fp) FILE *fp; { game_ptr key = (game_ptr) safe_malloc(sizeof(game_t)); char in[1024]; key->name = NULL; key->date = NULL; key->company = NULL; key->flags = 0; key->produced = NULL; key->players = NULL; key->text = NULL; prompt("Game Name :",in,fp); if(in[0]) key->name = newstr(in); prompt("Date :",in,fp); if(in[0]) key->date = newstr(in); prompt("Company :",in,fp); if(in[0]) key->company = newstr(in); prompt("# Players :",in,fp); if(in[0]) key->players = newstr(in); prompt("# Produced:",in,fp); if(in[0]) key->produced = newstr(in); prompt("Text :",in,fp); if(in[0]) key->text = newstr(in); prompt("Flags? y/n:",in,fp); if(tolower(in[0]) == 'y') { prompt(" 3D :",in,fp); if(tolower(in[0]) == 'y') key->flags |= F_3D; prompt(" BnW :",in,fp); if(tolower(in[0]) == 'y') key->flags |= F_BNW; prompt(" Laser :",in,fp); if(tolower(in[0]) == 'y') key->flags |= F_LASER; prompt(" Vector :",in,fp); if(tolower(in[0]) == 'y') key->flags |= F_VECTOR; prompt(" Pinball :",in,fp); if(tolower(in[0]) == 'y') key->flags |= F_PINBALL; } return(key); } static char *cmd_help[NUM_CMD] = { "", "", "Quits out of program", "Search database for entries", "Enable full descriptions", "Enable brief descriptions", "Show this info", "Send output to specified file", "Read a new game list", "Append a new game list to database" }; static command_t cmds[] = { { "?", C_HELP }, { "Append", C_APPEND }, { "Brief", C_BRIEF }, { "Exit", C_QUIT }, { "Find", C_FIND }, { "Help", C_HELP }, { "LOG", C_LOG, }, { "LONg", C_LONG }, { "Quit", C_QUIT }, { "Read", C_READ }, { "Search", C_FIND } }; void split_string(s,argc,argv) char *s; int *argc; char *argv[MAX_PARAMS]; { char *token; *argc = 0; do { while(*s == ' ') s++; /* skip leading spaces */ token = s; while(*s && *s!='\n' && *s!=' ') s++; /* skip to end of token */ if(token != s) { if(*s) *s++ = '\0'; argv[*argc] = token; (*argc)++; } } while (token != s && *argc < MAX_PARAMS); } type_t check_commands(cmd,margc,margv) char *cmd; int *margc; char *margv[MAX_PARAMS]; { type_t cmd_type = C_NONE; int match = 0; int i; split_string(cmd,margc,margv); if(*margc) { int len = strlen(margv[0]); for(i=0;i 1) cmd_type = C_AMB; } return(cmd_type); } int main(argc,argv) int argc; char *argv[]; { list_ptr l; char cmd[1024]; int brief = 1; int i; type_t cmd_type; FILE *log = stdout; l = list_create(); for(i=1;i",cmd,stdin); cmd_type = check_commands(cmd,&margc,margv); switch(cmd_type) { case C_QUIT: break; case C_FIND: key = get_search_key(stdin); list_matches(l,key,log,(brief)?game_print_brief:game_print); game_destroy(key); break; case C_LONG: brief = 0; break; case C_BRIEF: brief = 1; break; case C_HELP: for(i=0;i