/* I interpret the "RomLink" bytecode. My "programs" are resources. */ #include #include #include #include #include // Symbolic constants for ROMLink opcodes. #define __RL_OP_CSTRING 0x80 #define __RL_OP_INCLUDE 0x81 #define __RL_OP_BEGIN 0x82 #define __RL_OP_END 0x83 #define __RL_OP_BLOCKSIZE 0x84 #define __RL_OP_ROMLENGTH 0x86 #define __RL_OP_ROMCRC 0x87 #define __RL_OP_TREESIZE 0x88 #define __RL_OP_ALIGN 0x89 #define __RL_OP_ANCHOR 0x8a #define __RL_OP_KEY 0xfe #define __RL_OP_COMMENT 0xff // Symbolic constants for ROMLink resource pattern selectors. #define __RL_SEL_FILENAME 1 #define __RL_SEL_NAME 2 #define __RL_SEL_TYPE 3 #define __RL_SEL_ID 4 #define __RL_SEL_LOCAL 5 /* GLOBALS used by get_program and free_program */ char blergh[] = "nodeformxfrmcstrlongstypexecpinisinivdevpramvmnalistspdrsdirboarsrscddirgdirvdirvendvmod"; ResType *global_type_list; long global_type_count; void to_pas(unsigned char *p, char *c) { int sl = strlen(c); p[0] = sl; memcpy(p+1, c, sl); } void get_program(unsigned char **prog_p, long *len_p, unsigned char *name) { long i; Handle hdl = NULL; for(i=0; i= opcode) { memcpy(right, program, opcode); right += opcode; program += opcode; } else if(__RL_OP_CSTRING == opcode) { long len_with_nul = strlen(program) + 1; memcpy(right, program, len_with_nul); right += len_with_nul; program += len_with_nul; if(len_with_nul & 1) { *right++ = 0; } } else if(__RL_OP_INCLUDE == opcode) { unsigned char selector; unsigned char *res_name_pstr = NULL; unsigned char *other_prog; long other_prog_len; long used_leftlen, used_rightlen; int result; while((selector = *program++) != 0) { if(selector == __RL_SEL_NAME) { res_name_pstr = program; program += *program + 1; } } if(!res_name_pstr) { fprintf(stderr, "INCLUDE opcode with unimplemented resource pattern selector\n"); return 1; } get_program(&other_prog, &other_prog_len, res_name_pstr); if(!other_prog) return 1; result = do_program(right, other_prog, other_prog_len, &used_leftlen, &used_rightlen); free_program(other_prog); if(result) return result; if(left != right && used_leftlen) { fprintf(stderr, "Overwrote to the left!\n"); return 1; } left = right - used_leftlen; right = right + used_rightlen; } else if(__RL_OP_BEGIN == opcode) { offset_field_bytes = *program++ / 8; /* how many bytes this is going to use */ real_left = left; /* for when we return to our senses */ real_right = right; left = right = fake_middle = left - 0x1000; /* off to lala land, with 4k of room */ } else if(__RL_OP_END == opcode) { long newstufflen = right - left; long offset; if(right > real_left) { fprintf(stderr, "Ran out of breathing room!\n"); return 1; } real_left -= newstufflen; /* my left including new stuff */ fake_middle += real_left - left; /* the middle of the new stuff */ memmove(real_left, left, newstufflen); left = real_left; /* get out of lala land */ right = real_right; offset = fake_middle - right; if((long)right & 1) offset += 1; /* pretend this field is long-aligned */ memcpy(right, (char *)(&offset) + 4 - offset_field_bytes, offset_field_bytes); //printf("%08x\n", offset); right += offset_field_bytes; offset_field_bytes = 0; } else if(__RL_OP_BLOCKSIZE == opcode) { fprintf(stderr, "BLOCKSIZE not implemented\n"); return 1; } else if(__RL_OP_ROMLENGTH == opcode) { put_len_here = (unsigned long *)right; right += 4; } else if(__RL_OP_ROMCRC == opcode) { put_crc_here = (unsigned long *)right; right += 4; } else if(__RL_OP_TREESIZE == opcode) { fprintf(stderr, "TREESIZE not implemented\n"); return 1; } else if(__RL_OP_ALIGN == opcode) { unsigned char align = *program++; while((unsigned long)right % align) { *right++ = 0; } } else if(__RL_OP_ANCHOR == opcode) { fprintf(stderr, "ANCHOR not implemented\n"); return 1; } else if(__RL_OP_KEY == opcode) { unsigned char key = *program++; /* nop */ } else if(__RL_OP_COMMENT == opcode) { fprintf(stderr, "COMMENT not implemented\n"); return 1; } else { fprintf(stderr, "Unknown opcode %d\n", opcode); return 1; } } if(put_len_here) *put_len_here = right - left; if(put_crc_here) { unsigned char *ptr; unsigned long sum; *put_crc_here = 0; sum = 0; ptr = left; for(ptr=left; ptr> 31); sum += *ptr; } *put_crc_here = sum; } *leftlenp = middle - left; *rightlenp = right - middle; return 0; } int main(int argc, char **argv) { int print_usage = 0; short *refnum_list; int refnum_count = 0; short refnum; Str255 pas; char *outfile = NULL; unsigned char *buf, *middle; unsigned char *prog; long prog_len; int result; long used_left, used_right; long i; short err; FInfo fi; FILE *f; long writesize, writtensize; global_type_list = (ResType *)blergh; global_type_count = 22; refnum_list = (short *)calloc(argc, sizeof *refnum_list); if(!refnum_list) { fprintf(stderr, "%s: extreme memory pressure. Quitting.\n", argv[0]); return 1; } for(i=1; i