static void emit_string_constant(struct q *q, const struct node *node) { char *dst, *src; str_size_t n = 0; /* XXX Must go first, cause expand_code may change q->code pointer */ if (q->code + q->cc + 2 + sizeof(n) + node->vec.len > q->code + q->cs) expand_code(q, node->vec.len + 2 + sizeof(n) + 1); dst = q->code + q->cc + 2 + sizeof(n); src = node->vec.ptr + 1; assert(node->vec.ptr[0] == '"'); assert(node->vec.ptr[node->vec.len - 1] == '"'); assert(dst + node->vec.len < q->code + q->cs); for (; src < node->vec.ptr + node->vec.len - 1; src++, n++) if (*src == '%') { dst[n] = hex_ascii_to_int(q,src[1],node->line_no) << 4; dst[n] |= hex_ascii_to_int(q, src[2], node->line_no); src += 2; } else { dst[n] = *src; } emit_byte(q, OP_PUSH); emit_byte(q, TYPE_STR); emit(q, &n, sizeof(n)); q->cc += n; }
long lzw_decode(void *source,unsigned char *target) //dekomprimuje lzw. Nevraci velikost, tu si musi program zajistit sam. { long bitpos=0; unsigned char *pp; int code,old,i; DOUBLE_S p; int old_first; int mask=0xff; pp=target; for(i=0;i<LZW_MAX_CODES;i++) compress_dic[i].first=0; clear: old_value=0; nextgroup=free_code; bitsize=init_bitsize; mask=(1<<bitsize)-1; code=input_code_c(source,&bitpos,bitsize,mask); old_first=expand_code(code,&target); old=code; while ((code=input_code_c(source,&bitpos,bitsize,mask))!=end_code) { if (code==clear_code) { goto clear; } else if (code<nextgroup) { old_first=expand_code(code,&target); p.group=old; p.chr=old_first; de_add_code(&p,&mask); old=code; } else { p.group=old; p.chr=old_first; de_add_code(&p,&mask); old_first=expand_code(code,&target); old=code; } } return target-pp; }
static void emit(struct q *q, const void *mem, int len) { if (q->code == NULL || q->cc + len >= q->cs) expand_code(q, CHUNK_SIZE); (void) memcpy(q->code + q->cc, mem, len); q->cc += len; }
int expand_code(int code,char **target) { static int first; if (code>end_code) { expand_code(compress_dic[code].group,target); **target = old_value = compress_dic[code].chr+old_value; (*target)++; } else { **target = old_value = code+old_value; (*target)++; first = code; } return first; }
int expand_code(int code,unsigned char **target) { static int first; if (code>end_code) { assert(compress_dic[code].group<code); expand_code(compress_dic[code].group,target); **target=old_value=(unsigned char)compress_dic[code].chr; (*target)++; } else { **target=old_value=code; (*target)++; first=code; } return first; }
int dothehardpart( void ) { int len, c, n=0; int faux_pas= 0; long codesize= 0; /* initialize globals */ numsyms= numlines= 0; /* begin scanning the input stream */ c= fgetc(fin); if(c != 0xf5) { warn("Hmmm... this doesn't look like an AmigaBASIC binary.\n" "My output will probably look a bit funny. Proceed, for a laugh."); } if( feof(fin) || ferror(fin) ) { warn("unexpected end of input -- no code, no symbols"); return 1; } /* read the code segment */ do { /* Stefan Reisner thought that AmigaBASIC encodes the length of a line * in a 2 byte word prefix. This is not the whole truth... * I've experienced that the first byte holds a flag (e.g. 0x80 indicates * a line number) and only the second byte encodes the length. */ c= fgetc(fin); /* flags */ if( len= fgetc(fin) ) { codesize += len; len-= 2; if( !feof(fin) && !ferror(fin) ) n= read_line(fin,len,c); } } while( len && n == len && !ferror(fin) && !feof(fin) ); if( len ) { if( n != len || ferror(fin) ) { warn("I'm confused; after having read the code segment, I still seem\n" "to want to go on. In fact I just wanted to read another %d bytes\n" "when a serious problem interrupted me. I'll try to forget about this.",len); } if( feof(fin) ) { warn("Uh, oh. I suspect there was a null missing at the end of the code segment,\n" "causing me to read past where I should stop.\n" "I'll forget about the symbols now. Proceed, with fingers crossed."); } } else if( feof(fin) || ferror(fin) ) /* and len <= 0 */ warn("This seems to be a funny program. The input ended without any symbol definitions.\n"); /* read the symbols */ if( !ferror(fin) && !feof(fin) ) { int ok= 1; #ifdef DEBUG if(debuglevel >= 1) fprintf(stderr,"skipping a '\\x%02x' character\n",fgetc(fin)); else #endif (void)fgetc(fin); /* skip null byte */ if( (codesize & 1) == 0 ) { #ifdef DEBUG if(debuglevel >= 1) fprintf(stderr,"skipping another '\\x%02x' character\n",fgetc(fin)); else #endif (void)fgetc(fin); } if( feof(fin) || ferror(fin) ) { warn("I was just about to read the symbols when I reached the end of file.\n" "Maybe we have a BASIC program without symbols? We'll see..."); } else do { len= fgetc(fin); if( !feof(fin) ) ok= read_sym(fin, len, numsyms++); } while( ok && !feof(fin) && !ferror(fin) ); if( !ok ) { warn("After having read %ld %s I couldn't get another %d bytes.\n" "Maybe there is not enough free store? I'll better stop reading symbols!", numsyms-1, (numsyms-1 == 1) ? "symbol": "symbols"); } } #ifdef DEBUG if(debuglevel >= 1) fprintf(stderr,"expanding %ld lines of code w/ %d symbols\n",numlines,numsyms); #endif expand_code(); /* we _must_ call these to become re-entrant */ free_symbols(); free_code(); return faux_pas; }