diff options
author | Eugene Sandulenko | 2018-12-18 22:53:30 +0100 |
---|---|---|
committer | Eugene Sandulenko | 2018-12-18 22:53:30 +0100 |
commit | 0dab01862c3c1e34a80a239788a1d81fd9b679fd (patch) | |
tree | 8a2e39089adddaa5dbb03030a9c92dd5c05dbca4 /engines/glk/tads/tads2 | |
parent | ba00661b3a531834e6f7d648144996540539573c (diff) | |
download | scummvm-rg350-0dab01862c3c1e34a80a239788a1d81fd9b679fd.tar.gz scummvm-rg350-0dab01862c3c1e34a80a239788a1d81fd9b679fd.tar.bz2 scummvm-rg350-0dab01862c3c1e34a80a239788a1d81fd9b679fd.zip |
JANITORIAL: Whitespace fixes
Diffstat (limited to 'engines/glk/tads/tads2')
-rw-r--r-- | engines/glk/tads/tads2/ler.cpp | 192 | ||||
-rw-r--r-- | engines/glk/tads/tads2/ler.h | 120 | ||||
-rw-r--r-- | engines/glk/tads/tads2/regex.h | 112 | ||||
-rw-r--r-- | engines/glk/tads/tads2/tads2_cmap.cpp | 418 |
4 files changed, 421 insertions, 421 deletions
diff --git a/engines/glk/tads/tads2/ler.cpp b/engines/glk/tads/tads2/ler.cpp index 970fe31d67..d996977f0e 100644 --- a/engines/glk/tads/tads2/ler.cpp +++ b/engines/glk/tads/tads2/ler.cpp @@ -29,102 +29,102 @@ namespace TADS2 { #define TRDLOGERR_PREFIX "\n[An error has occurred within TADS: " int errcxdef::errfmt(char *outbuf, int outbufl, char *fmt, int argc, erradef *argv) { - int outlen = 0; - int argi = 0; - int len; - char buf[20]; - const char *p = nullptr; - char fmtchar; - - while (*fmt != '\0' && outbufl > 1) { - switch(*fmt) { - case '\\': - ++fmt; - len = 1; - switch(*fmt) { - case '\0': - --fmt; - break; - case '\n': - p = "\n"; - break; - case '\t': - p = "\t"; - break; - default: - p = fmt; - break; - } - break; - - case '%': - ++fmt; - fmtchar = *fmt; - if (argi >= argc) fmtchar = 1; // too many - ignore it - switch(fmtchar) { - case '\0': - --fmt; - len = 0; - break; - - case '%': - p = "%"; - len = 1; - break; - - case 'd': - sprintf(buf, "%d", argv[argi].erraint); - len = strlen(buf); - p = buf; - break; - - case 'u': - sprintf(buf, "%u", argv[argi].erraint); - len = strlen(buf); - p = buf; - break; - - case 's': - p = argv[argi].errastr; - len = strlen(p); - break; - - default: - p = ""; - len = 0; - --argi; - break; - } - ++argi; - break; - - default: - p = fmt; - len = 1; - break; - } - - /* copy output that was set up above */ - if (len != 0) { - if (outbufl >= len) { - memcpy(outbuf, p, (size_t)len); - outbufl -= len; - outbuf += len; - } else if (outbufl > 1) { - memcpy(outbuf, p, (size_t)outbufl - 1); - outbufl = 1; - } - outlen += len; - } - ++fmt; - } - - // add a null terminator - if (outbufl != 0) - *outbuf++ = '\0'; - - // return the length - return outlen; + int outlen = 0; + int argi = 0; + int len; + char buf[20]; + const char *p = nullptr; + char fmtchar; + + while (*fmt != '\0' && outbufl > 1) { + switch(*fmt) { + case '\\': + ++fmt; + len = 1; + switch(*fmt) { + case '\0': + --fmt; + break; + case '\n': + p = "\n"; + break; + case '\t': + p = "\t"; + break; + default: + p = fmt; + break; + } + break; + + case '%': + ++fmt; + fmtchar = *fmt; + if (argi >= argc) fmtchar = 1; // too many - ignore it + switch(fmtchar) { + case '\0': + --fmt; + len = 0; + break; + + case '%': + p = "%"; + len = 1; + break; + + case 'd': + sprintf(buf, "%d", argv[argi].erraint); + len = strlen(buf); + p = buf; + break; + + case 'u': + sprintf(buf, "%u", argv[argi].erraint); + len = strlen(buf); + p = buf; + break; + + case 's': + p = argv[argi].errastr; + len = strlen(p); + break; + + default: + p = ""; + len = 0; + --argi; + break; + } + ++argi; + break; + + default: + p = fmt; + len = 1; + break; + } + + /* copy output that was set up above */ + if (len != 0) { + if (outbufl >= len) { + memcpy(outbuf, p, (size_t)len); + outbufl -= len; + outbuf += len; + } else if (outbufl > 1) { + memcpy(outbuf, p, (size_t)outbufl - 1); + outbufl = 1; + } + outlen += len; + } + ++fmt; + } + + // add a null terminator + if (outbufl != 0) + *outbuf++ = '\0'; + + // return the length + return outlen; } void errcxdef::errcxlog(void *ctx0, char *fac, int err, int argc, erradef *argv) { diff --git a/engines/glk/tads/tads2/ler.h b/engines/glk/tads/tads2/ler.h index 8edb945115..57e3e63c2c 100644 --- a/engines/glk/tads/tads2/ler.h +++ b/engines/glk/tads/tads2/ler.h @@ -337,22 +337,22 @@ enum ErrorCode { /* * Special error flag - this is returned from execmd() when preparseCmd * returns a command list. This indicates to voc1cmd that it should try - * the command over again, using the words in the new list. + * the command over again, using the words in the new list. */ #define ERR_PREPRSCMDREDO 30000 /* preparseCmd returned a list */ #define ERR_PREPRSCMDCAN 30001 /* preparseCmd returned 'nil' to cancel */ union erradef { - int erraint; // integer argument - char *errastr; // text string argument + int erraint; // integer argument + char *errastr; // text string argument }; struct errdef { - errdef * errprv; // previous error frame - int errcode; // error code of exception being handled - char errfac[ERRFACMAX+1]; // facility of current error - erradef erraav[10]; // parameters for error - int erraac; // count of parameters in argc + errdef * errprv; // previous error frame + int errcode; // error code of exception being handled + char errfac[ERRFACMAX+1]; // facility of current error + erradef erraav[10]; // parameters for error + int erraac; // count of parameters in argc // jmp_buf errbuf; // jump buffer for current error frame }; @@ -362,21 +362,21 @@ class TADS2; // seek location record for an error message by number struct errmfdef { - uint errmfnum; // error number - size_t errmfseek; // seek location of this message + uint errmfnum; // error number + size_t errmfseek; // seek location of this message }; class errcxdef { public: errdef *errcxptr; // current error frame - void *errcxlgc; // context for error logging callback - int errcxofs; // offset in argument buffer - char errcxbuf[ERRBUFSIZ]; // space for argument strings - Common::SeekableReadStream *errcxfp; // message file, if one is being used - errmfdef *errcxseek; // seek locations of messages in file - uint errcxsksz; // size of errcxseek array - size_t errcxbase; // offset in physical file of logical error file - TADS2 * errcxappctx; // host application context + void *errcxlgc; // context for error logging callback + int errcxofs; // offset in argument buffer + char errcxbuf[ERRBUFSIZ]; // space for argument strings + Common::SeekableReadStream *errcxfp; // message file, if one is being used + errmfdef *errcxseek; // seek locations of messages in file + uint errcxsksz; // size of errcxseek array + size_t errcxbase; // offset in physical file of logical error file + TADS2 * errcxappctx; // host application context public: /** * Format an error message, sprintf-style, using arguments in an @@ -403,45 +403,45 @@ public: // begin protected code #define ERRBEGIN(ctx) \ { \ - errdef fr_; \ - if ((fr_.errcode = setjmp(fr_.errbuf)) == 0) \ - { \ - fr_.errprv = (ctx)->errcxptr; \ - (ctx)->errcxptr = &fr_; + errdef fr_; \ + if ((fr_.errcode = setjmp(fr_.errbuf)) == 0) \ + { \ + fr_.errprv = (ctx)->errcxptr; \ + (ctx)->errcxptr = &fr_; // end protected code, begin error handler #define ERRCATCH(ctx, e) \ - assert(1==1 && (ctx)->errcxptr != fr_.errprv); \ - (ctx)->errcxptr = fr_.errprv; \ - } \ - else \ - { \ - assert(2==2 && (ctx)->errcxptr != fr_.errprv); \ - (e) = fr_.errcode; \ - (ctx)->errcxptr = fr_.errprv; + assert(1==1 && (ctx)->errcxptr != fr_.errprv); \ + (ctx)->errcxptr = fr_.errprv; \ + } \ + else \ + { \ + assert(2==2 && (ctx)->errcxptr != fr_.errprv); \ + (e) = fr_.errcode; \ + (ctx)->errcxptr = fr_.errprv; // retrieve argument (int, string) in current error frame #define errargint(argnum) (fr_.erraav[argnum].erraint) #define errargstr(argnum) (fr_.erraav[argnum].errastr) - + #define ERREND(ctx) \ - } \ + } \ } // end protected code, begin cleanup (no handling; just cleaning up) #define ERRCLEAN(ctx) \ - assert((ctx)->errcxptr != fr_.errprv); \ - (ctx)->errcxptr = fr_.errprv; \ - } \ - else \ - { \ - assert((ctx)->errcxptr != fr_.errprv); \ - (ctx)->errcxptr = fr_.errprv; + assert((ctx)->errcxptr != fr_.errprv); \ + (ctx)->errcxptr = fr_.errprv; \ + } \ + else \ + { \ + assert((ctx)->errcxptr != fr_.errprv); \ + (ctx)->errcxptr = fr_.errprv; #define ERRENDCLN(ctx) \ - errrse(ctx); \ - } \ + errrse(ctx); \ + } \ } @@ -457,7 +457,7 @@ public: #ifdef ERR_NO_MACRO char *errstr(errcxdef *ctx, const char *str, int len); #else /* ERR_NO_MACRO */ - + #define errstr(ctx,str,len) \ ((memcpy(&(ctx)->errcxbuf[(ctx)->errcxofs],str,(size_t)len), \ (ctx)->errcxofs += (len), \ @@ -478,13 +478,13 @@ void errsign(errcxdef *ctx, int e, char *facility); void errjmp(jmp_buf buf, int e); # define errsign(ctx, e, fac) \ (strncpy((ctx)->errcxptr->errfac, fac, ERRFACMAX),\ - (ctx)->errcxptr->errfac[ERRFACMAX]='\0',\ - (ctx)->errcxofs=0, errjmp((ctx)->errcxptr->errbuf, e)) + (ctx)->errcxptr->errfac[ERRFACMAX]='\0',\ + (ctx)->errcxofs=0, errjmp((ctx)->errcxptr->errbuf, e)) # else /* DEBUG */ # define errsign(ctx, e, fac) \ (strncpy((ctx)->errcxptr->errfac, fac, ERRFACMAX),\ - (ctx)->errcxptr->errfac[ERRFACMAX]='\0',\ - (ctx)->errcxofs=0, longjmp((ctx)->errcxptr->errbuf, e)) + (ctx)->errcxptr->errfac[ERRFACMAX]='\0',\ + (ctx)->errcxofs=0, longjmp((ctx)->errcxptr->errbuf, e)) # endif /* DEBUG */ #endif /* ERR_NO_MACRO */ @@ -495,7 +495,7 @@ void errsigf(errcxdef *ctx, char *facility, int err); #else /* ERR_NO_MACRO */ #define errsigf(ctx, fac, e) (errargc(ctx,0),errsign(ctx,e,fac)) #endif /* ERR_NO_MACRO */ - + // signal an error with one argument #define errsigf1(ctx, fac, e, typ1, arg1) \ (errargv(ctx,0,typ1,arg1),errargc(ctx,1),errsign(ctx,e,fac)) @@ -515,7 +515,7 @@ void errrse1(errcxdef *ctx, errdef *fr); # define errrse(ctx) \ (errargc(ctx, fr_.erraac),\ memcpy((ctx)->errcxptr->erraav, fr_.erraav, \ - (size_t)(fr_.erraac*sizeof(erradef))),\ + (size_t)(fr_.erraac*sizeof(erradef))),\ errsign(ctx, fr_.errcode, fr_.errfac)) #endif /* ERR_NO_MACRO */ @@ -525,20 +525,20 @@ void errrse1(errcxdef *ctx, errdef *fr); * parameters from the error currently being handled to the enclosing * frame. This is useful when "keeping" an error being handled - i.e., * the arguments will continue to be used outside of the - * ERRCATCH..ERREND code. + * ERRCATCH..ERREND code. */ #define errkeepargs(ctx) errcopyargs(ctx, &fr_) -/** +/** * copy the parameters for an error from another frame into the current * frame - this can be used when we want to be able to display an error * that occurred in an inner frame within code that is protected by a - * new enclosing error frame + * new enclosing error frame */ #define errcopyargs(ctx, fr) \ (errargc((ctx), (fr)->erraac), \ - memcpy((ctx)->errcxptr->erraav, (fr)->erraav, \ - (size_t)((fr)->erraac*sizeof(erradef)))) + memcpy((ctx)->errcxptr->erraav, (fr)->erraav, \ + (size_t)((fr)->erraac*sizeof(erradef)))) // log error that's been caught, using arguments already caught #define errclog(ctx) \ @@ -576,14 +576,14 @@ void errlogf(errcxdef *ctx, char *facility, int err); // log an error with one argument #define errlogf1(ctx, fac, e, typ1, arg1) \ (errargv(ctx,0,typ1,arg1),errargc(ctx,1),errlogn(ctx,e,fac)) - + // log an error with two arguments #define errlogf2(ctx, fac, e, typ1, arg1, typ2, arg2) \ (errargv(ctx,0,typ1,arg1),errargv(ctx,1,typ2,arg2),\ errargc(ctx,2),errlogn(ctx,e,fac)) /** - * For compatility with old facility-free mechanism, signal with facility "TADS" + * For compatility with old facility-free mechanism, signal with facility "TADS" */ #define errsig(ctx, err) errsigf(ctx, "TADS", err) #define errsig1(c, e, t, a) errsigf1(c,"TADS",e,t,a) @@ -593,10 +593,10 @@ void errlogf(errcxdef *ctx, char *facility, int err); #define errlog2(c, e, t1, a1, t2, a2) errlogf2(c,"TADS",e,t1,a1,t2,a2) #define errsig2(c, e, t1, a1, t2, a2) error("Error occurred") - + // get the text of an error void errmsg(errcxdef *ctx, char *outbuf, uint outbufl, uint err); - + // initialize error subsystem, opening error message file if necessary void errini(errcxdef *ctx, Common::SeekableReadStream *fp); @@ -606,8 +606,8 @@ void lerfre(errcxdef *ctx); // error message structure - number + text struct errmdef { - uint errmerr; // error number - char *errmtxt; // text of error message + uint errmerr; // error number + char *errmtxt; // text of error message }; } // End of namespace TADS2 diff --git a/engines/glk/tads/tads2/regex.h b/engines/glk/tads/tads2/regex.h index 9040a029f3..e945efb65f 100644 --- a/engines/glk/tads/tads2/regex.h +++ b/engines/glk/tads/tads2/regex.h @@ -48,11 +48,11 @@ typedef int re_state_id; /** * Group register structure. Each register keeps track of the starting - * and ending offset of the group's text. + * and ending offset of the group's text. */ struct re_group_register { - const char *start_ofs; - const char *end_ofs; + const char *start_ofs; + const char *end_ofs; }; /** @@ -65,26 +65,26 @@ struct re_group_register { * complete set of transitions out of a particular state. A particular * state can have one character transition, or two epsilon transitions. * Note that we don't need to store the state ID in the tuple, because - * the state ID is the index of the tuple in an array of state tuples. + * the state ID is the index of the tuple in an array of state tuples. */ struct re_tuple { - // the character we must match to transition to the target state - char ch; + // the character we must match to transition to the target state + char ch; - // the target states - re_state_id next_state_1; - re_state_id next_state_2; + // the target states + re_state_id next_state_1; + re_state_id next_state_2; - // character range match table, if used - unsigned char *char_range; + // character range match table, if used + unsigned char *char_range; - // flags - byte flags; + // flags + byte flags; }; /** - * Tuple flags + * Tuple flags */ enum { // this state is the start of a group - the 'ch' value is the group ID @@ -95,25 +95,25 @@ enum { }; /** - * Status codes + * Status codes */ typedef enum { - // success - RE_STATUS_SUCCESS = 0, + // success + RE_STATUS_SUCCESS = 0, - // compilation error - group nesting too deep - RE_STATUS_GROUP_NESTING_TOO_DEEP + // compilation error - group nesting too deep + RE_STATUS_GROUP_NESTING_TOO_DEEP } re_status_t; /** * Regular expression compilation. This tracks the state of the compilation and - * stores the resources associated with the compiled expression. + * stores the resources associated with the compiled expression. */ class re_context { /** * A machine description. Machines are fully described by their initial - * and final state ID's. + * and final state ID's. */ struct re_machine { re_state_id init; ///< the machine's initial state @@ -168,7 +168,7 @@ private: void build_group_matcher(re_machine *machine, int group_num); /** - * Build a concatenation recognizer + * Build a concatenation recognizer */ void build_concat(re_machine *new_machine, re_machine *lhs, re_machine *rhs); @@ -180,7 +180,7 @@ private: void build_group(re_machine *new_machine, re_machine *sub_machine, int group_id); /** - * Build an alternation recognizer + * Build an alternation recognizer */ void build_alter(re_machine *new_machine, re_machine *lhs, re_machine *rhs); @@ -202,12 +202,12 @@ private: * first machine with the resulting machine. If the first machine is a * null machine, this simply replaces the first machine with the second * machine. If the second machine is null, this simply leaves the first - * machine unchanged. + * machine unchanged. */ void alternate_onto(re_machine *dest, re_machine *rhs); /** - * Compile an expression + * Compile an expression */ re_status_t compile(const char *expr, size_t exprlen, re_machine *result_machine); @@ -243,42 +243,42 @@ private: void save_search_str(const char *str, size_t len); public: errcxdef *_errctx; ///< error context - re_state_id _next_state; ///< next available state ID - - /** - * The array of transition tuples. We'll allocate this array and - * expand it as necessary. - */ - Common::Array<re_tuple> _tuple_arr; - - // current group ID - int _cur_group; - - // group registers - re_group_register _regs[RE_GROUP_REG_CNT]; - - /** - * Buffer for retaining a copy of the last string we scanned. We - * retain our own copy of each string, and point the group registers - * into this copy rather than the caller's original string -- this - * ensures that the group registers remain valid even after the - * caller has deallocated the original string. - */ - char *_strbuf; - - /** + re_state_id _next_state; ///< next available state ID + + /** + * The array of transition tuples. We'll allocate this array and + * expand it as necessary. + */ + Common::Array<re_tuple> _tuple_arr; + + // current group ID + int _cur_group; + + // group registers + re_group_register _regs[RE_GROUP_REG_CNT]; + + /** + * Buffer for retaining a copy of the last string we scanned. We + * retain our own copy of each string, and point the group registers + * into this copy rather than the caller's original string -- this + * ensures that the group registers remain valid even after the + * caller has deallocated the original string. + */ + char *_strbuf; + + /** * length of the string currently in the buffer */ - size_t _curlen; + size_t _curlen; - /** + /** * size of the buffer allocated to strbuf */ - size_t _strbufsiz; + size_t _strbufsiz; public: /** * Constructor. The memory for the context structure itself - * must be allocated and maintained by the caller. + * must be allocated and maintained by the caller. */ re_context(errcxdef *errctx); @@ -288,13 +288,13 @@ public: ~re_context(); /** - * Allocate a new state ID + * Allocate a new state ID */ re_state_id alloc_state(); /** * Compile an expression and search for a match within the given string. - * Returns the offset of the match, or -1 if no match was found. + * Returns the offset of the match, or -1 if no match was found. */ int compile_and_search(const char *pattern, size_t patlen, const char *searchstr, size_t searchlen, int *result_len); @@ -302,7 +302,7 @@ public: /** * Compile an expression and check for a match. Returns the length of the match * if we found a match, -1 if we found no match. This is not a search function; - * we merely match the leading substring of the given string to the given pattern. + * we merely match the leading substring of the given string to the given pattern. */ int compile_and_match(const char *pattern, size_t patlen, const char *searchstr, size_t searchlen); diff --git a/engines/glk/tads/tads2/tads2_cmap.cpp b/engines/glk/tads/tads2/tads2_cmap.cpp index cf63c9a763..68945f7336 100644 --- a/engines/glk/tads/tads2/tads2_cmap.cpp +++ b/engines/glk/tads/tads2/tads2_cmap.cpp @@ -29,238 +29,238 @@ namespace TADS2 { /** * Signatures for character map files. The signature is stored at the - * beginning of the file. + * beginning of the file. */ // single-byte character map version 1.0.0 #define CMAP_SIG_S100 "TADS2 charmap S100\n\r\01a" void TADS2::cmap_init_default() { - size_t i; + size_t i; - // initialize the input table - for (i = 0 ; i < sizeof(G_cmap_input)/sizeof(G_cmap_input[0]) ; ++i) - G_cmap_input[i] = (unsigned char)i; + // initialize the input table + for (i = 0 ; i < sizeof(G_cmap_input)/sizeof(G_cmap_input[0]) ; ++i) + G_cmap_input[i] = (unsigned char)i; - // initialize the output table - for (i = 0 ; i < sizeof(G_cmap_output)/sizeof(G_cmap_output[0]) ; ++i) - G_cmap_output[i] = (unsigned char)i; + // initialize the output table + for (i = 0 ; i < sizeof(G_cmap_output)/sizeof(G_cmap_output[0]) ; ++i) + G_cmap_output[i] = (unsigned char)i; - // we have a null ID - memset(G_cmap_id, 0, sizeof(G_cmap_id)); + // we have a null ID + memset(G_cmap_id, 0, sizeof(G_cmap_id)); - // indicate that it's the default - strcpy(G_cmap_ldesc, "(native/no mapping)"); + // indicate that it's the default + strcpy(G_cmap_ldesc, "(native/no mapping)"); - // note that we have no character set loaded - S_cmap_loaded = false; + // note that we have no character set loaded + S_cmap_loaded = false; } int TADS2::cmap_load_internal(const char *filename) { - osfildef *fp; - static char sig1[] = CMAP_SIG_S100; - char buf[256]; - uchar lenbuf[2]; - size_t len; - int sysblk; - - // if there's no mapping file, use the default mapping - if (filename == 0) { - // initialize with the default mapping - cmap_init_default(); - - // return success - return 0; - } - - // open the file - fp = osfoprb(filename, OSFTCMAP); - if (fp == 0) - return 1; - - // check the signature - if (osfrb(fp, buf, sizeof(sig1)) - || memcmp(buf, sig1, sizeof(sig1)) != 0) { - osfcls(fp); - return 2; - } - - // load the ID - G_cmap_id[4] = '\0'; - if (osfrb(fp, G_cmap_id, 4)) { - osfcls(fp); - return 3; - } - - // load the long description - if (osfrb(fp, lenbuf, 2) - || (len = osrp2(lenbuf)) > sizeof(G_cmap_ldesc) - || osfrb(fp, G_cmap_ldesc, len)) { - osfcls(fp); - return 4; - } - - // load the two tables - input, then output - if (osfrb(fp, G_cmap_input, sizeof(G_cmap_input)) - || osfrb(fp, G_cmap_output, sizeof(G_cmap_output))) { - osfcls(fp); - return 5; - } - - // read the next section header - if (osfrb(fp, buf, 4)) { - osfcls(fp); - return 6; - } - - // if it's "SYSI", read the system information string - if (!memcmp(buf, "SYSI", 4)) { - // read the length prefix, then the string - if (osfrb(fp, lenbuf, 2) - || (len = osrp2(lenbuf)) > sizeof(buf) - || osfrb(fp, buf, len)) { - osfcls(fp); - return 7; - } - - // we have a system information block - sysblk = true; - } else { - // there's no system information block - sysblk = false; - } - - /* - * call the OS code, so that it can do any system-dependent - * initialization for the new character mapping - */ - os_advise_load_charmap(G_cmap_id, G_cmap_ldesc, sysblk ? buf : ""); - - // read the next section header - if (sysblk && osfrb(fp, buf, 4)) { - osfcls(fp); - return 8; - } - - // see if we have an entity list - if (!memcmp(buf, "ENTY", 4)) { - // read the entities - for (;;) { - unsigned int cval; - char expansion[CMAP_MAX_ENTITY_EXPANSION]; - - // read the next item's length and character value - if (osfrb(fp, buf, 4)) { - osfcls(fp); - return 9; - } - - // decode the values - len = osrp2(buf); - cval = osrp2(buf+2); - - // if we've reached the zero marker, we're done - if (len == 0 && cval == 0) - break; - - // read the string - if (len > CMAP_MAX_ENTITY_EXPANSION - || osfrb(fp, expansion, len)) { - osfcls(fp); - return 10; - } - - // tell the output code about the expansion - tio_set_html_expansion(cval, expansion, len); - } - } - - /* - * ignore anything else we find - if the file format is updated to - * include extra information in the future, and this old code tries - * to load an updated file, we'll just ignore the new information, - * which should always be placed after the "SYSI" block (if present) - * to ensure compatibility with past versions (such as this code) - */ - // no problems - close the file and return success - osfcls(fp); - return 0; + osfildef *fp; + static char sig1[] = CMAP_SIG_S100; + char buf[256]; + uchar lenbuf[2]; + size_t len; + int sysblk; + + // if there's no mapping file, use the default mapping + if (filename == 0) { + // initialize with the default mapping + cmap_init_default(); + + // return success + return 0; + } + + // open the file + fp = osfoprb(filename, OSFTCMAP); + if (fp == 0) + return 1; + + // check the signature + if (osfrb(fp, buf, sizeof(sig1)) + || memcmp(buf, sig1, sizeof(sig1)) != 0) { + osfcls(fp); + return 2; + } + + // load the ID + G_cmap_id[4] = '\0'; + if (osfrb(fp, G_cmap_id, 4)) { + osfcls(fp); + return 3; + } + + // load the long description + if (osfrb(fp, lenbuf, 2) + || (len = osrp2(lenbuf)) > sizeof(G_cmap_ldesc) + || osfrb(fp, G_cmap_ldesc, len)) { + osfcls(fp); + return 4; + } + + // load the two tables - input, then output + if (osfrb(fp, G_cmap_input, sizeof(G_cmap_input)) + || osfrb(fp, G_cmap_output, sizeof(G_cmap_output))) { + osfcls(fp); + return 5; + } + + // read the next section header + if (osfrb(fp, buf, 4)) { + osfcls(fp); + return 6; + } + + // if it's "SYSI", read the system information string + if (!memcmp(buf, "SYSI", 4)) { + // read the length prefix, then the string + if (osfrb(fp, lenbuf, 2) + || (len = osrp2(lenbuf)) > sizeof(buf) + || osfrb(fp, buf, len)) { + osfcls(fp); + return 7; + } + + // we have a system information block + sysblk = true; + } else { + // there's no system information block + sysblk = false; + } + + /* + * call the OS code, so that it can do any system-dependent + * initialization for the new character mapping + */ + os_advise_load_charmap(G_cmap_id, G_cmap_ldesc, sysblk ? buf : ""); + + // read the next section header + if (sysblk && osfrb(fp, buf, 4)) { + osfcls(fp); + return 8; + } + + // see if we have an entity list + if (!memcmp(buf, "ENTY", 4)) { + // read the entities + for (;;) { + unsigned int cval; + char expansion[CMAP_MAX_ENTITY_EXPANSION]; + + // read the next item's length and character value + if (osfrb(fp, buf, 4)) { + osfcls(fp); + return 9; + } + + // decode the values + len = osrp2(buf); + cval = osrp2(buf+2); + + // if we've reached the zero marker, we're done + if (len == 0 && cval == 0) + break; + + // read the string + if (len > CMAP_MAX_ENTITY_EXPANSION + || osfrb(fp, expansion, len)) { + osfcls(fp); + return 10; + } + + // tell the output code about the expansion + tio_set_html_expansion(cval, expansion, len); + } + } + + /* + * ignore anything else we find - if the file format is updated to + * include extra information in the future, and this old code tries + * to load an updated file, we'll just ignore the new information, + * which should always be placed after the "SYSI" block (if present) + * to ensure compatibility with past versions (such as this code) + */ + // no problems - close the file and return success + osfcls(fp); + return 0; } int TADS2::cmap_load(const char *filename) { - int err; - - // try loading the file - if ((err = cmap_load_internal(filename)) != 0) - return err; - - /* - * note that we've explicitly loaded a character set, if they named - * a character set (if not, this simply establishes the default - * setting, so we haven't explicitly loaded anything) - */ - if (filename != nullptr) - S_cmap_loaded = true; - - // success - return 0; + int err; + + // try loading the file + if ((err = cmap_load_internal(filename)) != 0) + return err; + + /* + * note that we've explicitly loaded a character set, if they named + * a character set (if not, this simply establishes the default + * setting, so we haven't explicitly loaded anything) + */ + if (filename != nullptr) + S_cmap_loaded = true; + + // success + return 0; } void TADS2::cmap_override() { - // apply the default mapping - cmap_init_default(); - - /* - * pretend we have a character map loaded, so that we don't try to - * load another one if the game specifies a character set - */ - S_cmap_loaded = true; + // apply the default mapping + cmap_init_default(); + + /* + * pretend we have a character map loaded, so that we don't try to + * load another one if the game specifies a character set + */ + S_cmap_loaded = true; } void TADS2::cmap_set_game_charset(errcxdef *ec, const char *internal_id, const char *internal_ldesc, const char *argv0) { - char filename[OSFNMAX]; - - /* - * If a character set is already explicitly loaded, ignore the - * game's character set - the player asked us to use a particular - * mapping, so ignore what the game wants. (This will probably - * result in incorrect display of non-ASCII character values, but - * the player is most likely to use this to avoid errors when an - * appropriate mapping file for the game is not available. In this - * case, the player informs us by setting the option that he or she - * knows and accepts that the game will not look exactly right.) - */ - if (S_cmap_loaded) - return; - - /* - * ask the operating system to name the mapping file -- this routine - * will determine, if possible, the current native character set, - * and apply a system-specific naming convention to tell us what - * mapping file we should open - */ - os_gen_charmap_filename(filename, internal_id, argv0); - - // try loading the mapping file - if (cmap_load_internal(filename)) - errsig2(ec, ERR_CHRNOFILE, - ERRTSTR, errstr(ec, filename, strlen(filename)), - ERRTSTR, errstr(ec, internal_ldesc, strlen(internal_ldesc))); - - /** - * We were successful - the game's internal character set is now - * mapped to the current native character set. Even though we - * loaded an ldesc from the mapping file, forget that and store the - * internal ldesc that the game specified. The reason we do this is - * that it's possible that the player will dynamically switch native - * character sets in the future, at which point we'll need to - * re-load the mapping table, which could raise an error if a - * mapping file for the new character set isn't available. So, we - * may need to provide the same explanation later that we needed to - * provide here. Save the game's character set ldesc for that - * eventuality, since it describes exactly what the *game* wanted. - */ - strcpy(G_cmap_ldesc, internal_ldesc); + char filename[OSFNMAX]; + + /* + * If a character set is already explicitly loaded, ignore the + * game's character set - the player asked us to use a particular + * mapping, so ignore what the game wants. (This will probably + * result in incorrect display of non-ASCII character values, but + * the player is most likely to use this to avoid errors when an + * appropriate mapping file for the game is not available. In this + * case, the player informs us by setting the option that he or she + * knows and accepts that the game will not look exactly right.) + */ + if (S_cmap_loaded) + return; + + /* + * ask the operating system to name the mapping file -- this routine + * will determine, if possible, the current native character set, + * and apply a system-specific naming convention to tell us what + * mapping file we should open + */ + os_gen_charmap_filename(filename, internal_id, argv0); + + // try loading the mapping file + if (cmap_load_internal(filename)) + errsig2(ec, ERR_CHRNOFILE, + ERRTSTR, errstr(ec, filename, strlen(filename)), + ERRTSTR, errstr(ec, internal_ldesc, strlen(internal_ldesc))); + + /** + * We were successful - the game's internal character set is now + * mapped to the current native character set. Even though we + * loaded an ldesc from the mapping file, forget that and store the + * internal ldesc that the game specified. The reason we do this is + * that it's possible that the player will dynamically switch native + * character sets in the future, at which point we'll need to + * re-load the mapping table, which could raise an error if a + * mapping file for the new character set isn't available. So, we + * may need to provide the same explanation later that we needed to + * provide here. Save the game's character set ldesc for that + * eventuality, since it describes exactly what the *game* wanted. + */ + strcpy(G_cmap_ldesc, internal_ldesc); } } // End of namespace TADS2 |