/* log.c: * This file deals with "wrong guess" logging, and "usefiles". * Both are read in at startup, and written out when the program quits. * * For usefile usage, we are using the pseudo-OO design of encapsulating * details in this file. So for this case, static globals are a GOOD THING. * It makes it seem like we have an implicit "usefile" object, that can * only be accessed through member functions listed in log.h */ #include #include #include #include #include #include #include #include #include "defs.h" #include "externs.h" #include "game.h" #include "badguess.h" #include "options.h" static char logfilename[200]; Boolean useKanji[MAXTRANSLATIONSALLOWED]; /* initlog() * Checks for existance of logfile, and reads in previously missed * count from that if possible. */ void initlog() { FILE *oldlogfile; char inbuf[100]; GetXtrmString("logfile", "Logfile", logfilename); if (access(logfilename, R_OK) != 0) return; oldlogfile = fopen(logfilename, "r"); if (oldlogfile == NULL) { printf("kdrill: Error... cannot open file %s\n", logfilename); return; } else { printf("Reading in %s for previously missed kanji\n", logfilename); } numberincorrect = 0; while (fgets(inbuf, 99, oldlogfile) != NULL) { int kindex; kindex = xtoi(inbuf); if (kindex < MAXTRANSLATIONSALLOWED) { if (translations[kindex] != NULL) { translations[kindex]->incorrect += 1; if (translations[kindex]->incorrect == 1) numberincorrect += 1; AdjustBadCache(translations[kindex]); } } } printf("Restored a total of %d incorrect kanji\n", numberincorrect); TallyWrong(); fclose(oldlogfile); } /* * This is a callback for the "Log" button, but can be called with * NULL arguments, and IS, at the end of the program. * * MakeLog dumps our error log out to the logfile. * Do it in a vaguely "usefile"-compatible format, in case the player * wants _repeated_ drilling on the chars missed. */ void MakeLog(Widget w, XtPointer client_data, XtPointer call_data) { int kcounter; char statbuf[200]; int errors = 0; FILE *logfile; if (numberincorrect == 0) { sprintf(statbuf, "Clearing log file \"%.190s\"", logfilename); setstatus(statbuf); /* DEUBG: print same message to stdout*/ printf("%s\n", statbuf); unlink(logfilename); return; } logfile = fopen(logfilename, "w"); if (logfile == NULL) { if (numberincorrect > 0) { sprintf(statbuf, "Error.. cannot open \"%.190s\"", logfilename); setstatus(statbuf); } return; } for (kcounter = lowestkanji; kcounter <= highestkanji; kcounter++) { if (translations[kcounter] == NULL) continue; if (translations[kcounter]->incorrect > 0) { int loop = translations[kcounter]->incorrect; while (loop-- > 0) { fprintf(logfile, "%x \n", kcounter); } errors++; } } fclose(logfile); if (errors > 0) { sprintf(statbuf, "Saved %d kanji to \"%.190s\"", errors, logfilename); setstatus(statbuf); printf("%s\n", statbuf); } } /*********************************************** * Now the Usefile section * ***********************************************/ int usefilecount = 0; int NumInUsefile() { return usefilecount; } /* If you're nice, use "False" or "True" as val */ void SetUseKanji(int kindex, int val) { int oldval = useKanji[kindex]; useKanji[kindex] = val; if (oldval == 0 && val == 1) usefilecount++; if (oldval == 1 && val == 0) usefilecount--; } int InUsefile(int kindex) { return useKanji[kindex]; } /* Save "usefile" entries, if appropriate */ void SaveUsefile() { int kcount = 0; char statbuf[200]; FILE *fptr; if(usefilecount <=0) { unlink(usefilename); return; } if (usefilecount < HAVE_AT_LEAST) { sprintf(statbuf, "WARNING: too few entries for usefile. Still saving to \"%.190s\"", usefilename); } fptr = fopen(usefilename, "w"); if (fptr == NULL) { sprintf(statbuf, "Error.. cannot open \"%.190s\"", logfilename); setstatus(statbuf); perror(statbuf); return; } for (kcount = lowestkanji; kcount <= highestkanji; kcount++) { if (InUsefile(kcount) == 0) continue; fprintf(fptr, "%x\n", kcount); } fclose(fptr); } /* getusefile: * Subroutine for initusefile(). * sets global FILE*usefile. * If possible, will get it from the user's home directory, * otherwise, tries current directory * This is NOT an exported routine: initusefile() is */ FILE * getusefile() { FILE *fptr; char fullname[100]; GetXtrmString("usefile", "Usefile", usefilename); #ifdef DEBUG puts(""); printf("usefile from resources is \"%s\"\n", usefilename); #endif /*if(usefilename == NULL) return NULL; */ fullname[0] = '\0'; if (strncmp(usefilename, "~/", 2) == 0) { sprintf(fullname, "%s%s", homedir, &usefilename[1]); strcpy(usefilename, fullname); } if ((fptr = fopen(usefilename, "r")) == NULL) { printf("Usefile %s does not exist. Using entire dictionary...\n", usefilename); } else { printf("using \"%s\" to abridge dictionary\n", usefilename); if (!useUsefile) puts("(-nousefile option used. Will not abridge, unless option is changed)"); } return fptr; } /* inituse: * revamped from 2.9.3 version. * Read in the "usefile", which should consist of * a list of hex SJIS indexes. * This sets useKanji[] appropriately. * * by default, zero out all entries. * Then set only entries mentioned in file to 1 instead of 0 * * Note that whether or not to pay attention to useKanji[], is * a separate variable, useUsefile */ void initusefile() { FILE *fptr; char inbuf[100]; int count = 0; /*first set all to UNREADABLE, for now */ bzero(useKanji, sizeof(Boolean[MAXTRANSLATIONSALLOWED])); fptr = getusefile(); if (fptr == NULL) { useUsefile = False; SetXtrmBoolean("nousefile", True); UpdateUsefileL(); return; } while (fgets(inbuf, 99, fptr) != NULL) { int usechar; usechar = xtoi(inbuf); if (usechar < MAXTRANSLATIONSALLOWED) { SetUseKanji(usechar, True); count++; } } printf("read %d entries in usefile\n", count); if ((count < HAVE_AT_LEAST) && useUsefile) { printf("Warning: Usefile exists with less than %d kanji.\n", HAVE_AT_LEAST); } }