/* It's very fast if there are few close misses. */ size_t CORD_str(CORD x, size_t start, CORD s) { CORD_pos xpos; size_t xlen = CORD_len(x); size_t slen; register size_t start_len; const char * s_start; unsigned long s_buf = 0; /* The first few characters of s */ unsigned long x_buf = 0; /* Start of candidate substring. */ /* Initialized only to make compilers */ /* happy. */ unsigned long mask = 0; register size_t i; register size_t match_pos; if (s == CORD_EMPTY) return(start); if (CORD_IS_STRING(s)) { s_start = s; slen = strlen(s); } else { s_start = CORD_to_char_star(CORD_substr(s, 0, sizeof(unsigned long))); slen = CORD_len(s); } if (xlen < start || xlen - start < slen) return(CORD_NOT_FOUND); start_len = slen; if (start_len > sizeof(unsigned long)) start_len = sizeof(unsigned long); CORD_set_pos(xpos, x, start); for (i = 0; i < start_len; i++) { mask <<= 8; mask |= 0xff; s_buf <<= 8; s_buf |= (unsigned char)s_start[i]; x_buf <<= 8; x_buf |= (unsigned char)CORD_pos_fetch(xpos); CORD_next(xpos); } for (match_pos = start; ; match_pos++) { if ((x_buf & mask) == s_buf) { if (slen == start_len || CORD_ncmp(x, match_pos + start_len, s, start_len, slen - start_len) == 0) { return(match_pos); } } if ( match_pos == xlen - slen ) { return(CORD_NOT_FOUND); } x_buf <<= 8; x_buf |= (unsigned char)CORD_pos_fetch(xpos); CORD_next(xpos); } }
CORD CORD_substr(CORD x, size_t i, size_t n) { size_t len = CORD_len(x); if (i >= len || n == 0) return(0); if (i + n > len) n = len - i; return(CORD_substr_checked(x, i, n)); }
CORD CORD_substr(CORD x, size_t i, size_t n) { register size_t len = CORD_len(x); if (i >= len || n <= 0) return(0); /* n < 0 is impossible in a correct C implementation, but */ /* quite possible under SunOS 4.X. */ if (i + n > len) n = len - i; return(CORD_substr_checked(x, i, n)); }
char * CORD_to_char_star(CORD x) { register size_t len = CORD_len(x); char * result = GC_MALLOC_ATOMIC(len + 1); if (result == 0) OUT_OF_MEMORY; CORD_fill_buf(x, 0, len, result); result[len] = '\0'; return(result); }
static int ec_len(CORD_ec x) { return(CORD_len(x[0].ec_cord) + (x[0].ec_bufptr - x[0].ec_buf)); }
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HANDLE hInstance; HDC dc; PAINTSTRUCT ps; RECT client_area; RECT this_line; RECT dummy; TEXTMETRIC tm; register int i; int id; switch (message) { case WM_CREATE: hInstance = ( (LPCREATESTRUCT) lParam)->hInstance; dc = GetDC(hwnd); SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT)); GetTextMetrics(dc, &tm); ReleaseDC(hwnd, dc); char_width = tm.tmAveCharWidth; char_height = tm.tmHeight + tm.tmExternalLeading; GetClientRect(hwnd, &client_area); COLS = (client_area.right - client_area.left)/char_width; LINES = (client_area.bottom - client_area.top)/char_height; generic_init(); return(0); case WM_CHAR: if (wParam == QUIT) { SendMessage( hwnd, WM_CLOSE, 0, 0L ); } else { do_command((int)wParam); } return(0); case WM_SETFOCUS: CreateCaret(hwnd, NULL, char_width, char_height); ShowCaret(hwnd); caret_visible = 1; update_cursor(); return(0); case WM_KILLFOCUS: HideCaret(hwnd); DestroyCaret(); caret_visible = 0; return(0); case WM_LBUTTONUP: { unsigned xpos = LOWORD(lParam); /* From left */ unsigned ypos = HIWORD(lParam); /* from top */ set_position(xpos / (unsigned)char_width, ypos / (unsigned)char_height); return(0); } case WM_COMMAND: id = LOWORD(wParam); if (id & EDIT_CMD_FLAG) { if (id & REPEAT_FLAG) do_command(REPEAT); do_command(CHAR_CMD(id)); return( 0 ); } else { switch(id) { case IDM_FILEEXIT: SendMessage( hwnd, WM_CLOSE, 0, 0L ); return( 0 ); case IDM_HELPABOUT: if( DialogBox( hInstance, "ABOUTBOX", hwnd, AboutBoxCallback ) ) InvalidateRect( hwnd, NULL, TRUE ); return( 0 ); case IDM_HELPCONTENTS: de_error( "Cursor keys: ^B(left) ^F(right) ^P(up) ^N(down)\n" "Undo: ^U Write: ^W Quit:^D Repeat count: ^R[n]\n" "Top: ^T Locate (search, find): ^L text ^L\n"); return( 0 ); } } break; case WM_CLOSE: DestroyWindow( hwnd ); return 0; case WM_DESTROY: PostQuitMessage (0); GC_win32_free_heap(); return 0; case WM_PAINT: dc = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &client_area); COLS = (client_area.right - client_area.left)/char_width; LINES = (client_area.bottom - client_area.top)/char_height; SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT)); for (i = 0; i < LINES; i++) { get_line_rect(i, client_area.right, &this_line); if (IntersectRect(&dummy, &this_line, &ps.rcPaint)) { CORD raw_line = retrieve_screen_line(i); size_t len = CORD_len(raw_line); char * text = CORD_to_char_star(raw_line); /* May contain embedded NULLs */ char * plain = plain_chars(text, len); char * blanks = CORD_to_char_star(CORD_chars(' ', COLS - len)); char * control = control_chars(text, len); # define RED RGB(255,0,0) SetBkMode(dc, OPAQUE); SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT)); TextOut(dc, this_line.left, this_line.top, plain, (int)len); TextOut(dc, this_line.left + (int)len * char_width, this_line.top, blanks, (int)(COLS - len)); SetBkMode(dc, TRANSPARENT); SetTextColor(dc, RED); TextOut(dc, this_line.left, this_line.top, control, (int)strlen(control)); } } EndPaint(hwnd, &ps); screen_was_painted = 1; return 0; } return DefWindowProc (hwnd, message, wParam, lParam); }
int CORD_riter(CORD x, CORD_iter_fn f1, void * client_data) { size_t len = CORD_len(x); if (len == 0) return(0); return(CORD_riter4(x, len - 1, f1, client_data)); }
void test_basics(void) { CORD x = CORD_from_char_star("ab"); register int i; char c; CORD y; CORD_pos p; x = CORD_cat(x,x); if (x == CORD_EMPTY) ABORT("CORD_cat(x,x) returned empty cord"); if (!CORD_IS_STRING(x)) ABORT("short cord should usually be a string"); if (strcmp(x, "abab") != 0) ABORT("bad CORD_cat result"); for (i = 1; i < 16; i++) { x = CORD_cat(x,x); } x = CORD_cat(x,"c"); if (CORD_len(x) != 128*1024+1) ABORT("bad length"); count = 0; if (CORD_iter5(x, 64*1024-1, test_fn, CORD_NO_FN, (void *)13) == 0) { ABORT("CORD_iter5 failed"); } if (count != 64*1024 + 2) ABORT("CORD_iter5 failed"); count = 0; CORD_set_pos(p, x, 64*1024-1); while(CORD_pos_valid(p)) { (void) test_fn(CORD_pos_fetch(p), (void *)13); CORD_next(p); } if (count != 64*1024 + 2) ABORT("Position based iteration failed"); y = CORD_substr(x, 1023, 5); if (!y) ABORT("CORD_substr returned NULL"); if (!CORD_IS_STRING(y)) ABORT("short cord should usually be a string"); if (strcmp(y, "babab") != 0) ABORT("bad CORD_substr result"); y = CORD_substr(x, 1024, 8); if (!y) ABORT("CORD_substr returned NULL"); if (!CORD_IS_STRING(y)) ABORT("short cord should usually be a string"); if (strcmp(y, "abababab") != 0) ABORT("bad CORD_substr result"); y = CORD_substr(x, 128*1024-1, 8); if (!y) ABORT("CORD_substr returned NULL"); if (!CORD_IS_STRING(y)) ABORT("short cord should usually be a string"); if (strcmp(y, "bc") != 0) ABORT("bad CORD_substr result"); x = CORD_balance(x); if (CORD_len(x) != 128*1024+1) ABORT("bad length"); count = 0; if (CORD_iter5(x, 64*1024-1, test_fn, CORD_NO_FN, (void *)13) == 0) { ABORT("CORD_iter5 failed"); } if (count != 64*1024 + 2) ABORT("CORD_iter5 failed"); y = CORD_substr(x, 1023, 5); if (!y) ABORT("CORD_substr returned NULL"); if (!CORD_IS_STRING(y)) ABORT("short cord should usually be a string"); if (strcmp(y, "babab") != 0) ABORT("bad CORD_substr result"); y = CORD_from_fn(id_cord_fn, 0, 13); i = 0; CORD_set_pos(p, y, i); while(CORD_pos_valid(p)) { c = CORD_pos_fetch(p); if(c != i) ABORT("Traversal of function node failed"); CORD_next(p); i++; } if (i != 13) ABORT("Bad apparent length for function node"); }
void test_extras(void) { # define FNAME1 "cordtst1.tmp" /* short name (8+3) for portability */ # define FNAME2 "cordtst2.tmp" register int i; CORD y = "abcdefghijklmnopqrstuvwxyz0123456789"; CORD x = "{}"; CORD w, z; FILE *f; FILE *f1a, *f1b, *f2; w = CORD_cat(CORD_cat(y,y),y); z = CORD_catn(3,y,y,y); if (CORD_cmp(w,z) != 0) ABORT("CORD_catn comparison wrong"); for (i = 1; i < 100; i++) { x = CORD_cat(x, y); } z = CORD_balance(x); if (CORD_cmp(x,z) != 0) ABORT("balanced string comparison wrong"); if (CORD_cmp(x,CORD_cat(z, CORD_nul(13))) >= 0) ABORT("comparison 2"); if (CORD_cmp(CORD_cat(x, CORD_nul(13)), z) <= 0) ABORT("comparison 3"); if (CORD_cmp(x,CORD_cat(z, "13")) >= 0) ABORT("comparison 4"); if ((f = fopen(FNAME1, "w")) == 0) ABORT("open failed"); if (CORD_put(z,f) == EOF) ABORT("CORD_put failed"); if (fclose(f) == EOF) ABORT("fclose failed"); f1a = fopen(FNAME1, "rb"); if (!f1a) ABORT("Unable to open " FNAME1); w = CORD_from_file(f1a); if (CORD_len(w) != CORD_len(z)) ABORT("file length wrong"); if (CORD_cmp(w,z) != 0) ABORT("file comparison wrong"); if (CORD_cmp(CORD_substr(w, 50*36+2, 36), y) != 0) ABORT("file substr wrong"); f1b = fopen(FNAME1, "rb"); if (!f1b) ABORT("2nd open failed: " FNAME1); z = CORD_from_file_lazy(f1b); if (CORD_cmp(w,z) != 0) ABORT("File conversions differ"); if (CORD_chr(w, 0, '9') != 37) ABORT("CORD_chr failed 1"); if (CORD_chr(w, 3, 'a') != 38) ABORT("CORD_chr failed 2"); if (CORD_rchr(w, CORD_len(w) - 1, '}') != 1) ABORT("CORD_rchr failed"); x = y; for (i = 1; i < 14; i++) { x = CORD_cat(x,x); } if ((f = fopen(FNAME2, "w")) == 0) ABORT("2nd open failed"); # ifdef __DJGPP__ /* FIXME: DJGPP workaround. Why does this help? */ if (fflush(f) != 0) ABORT("fflush failed"); # endif if (CORD_put(x,f) == EOF) ABORT("CORD_put failed"); if (fclose(f) == EOF) ABORT("fclose failed"); f2 = fopen(FNAME2, "rb"); if (!f2) ABORT("Unable to open " FNAME2); w = CORD_from_file(f2); if (CORD_len(w) != CORD_len(x)) ABORT("file length wrong"); if (CORD_cmp(w,x) != 0) ABORT("file comparison wrong"); if (CORD_cmp(CORD_substr(w, 1000*36, 36), y) != 0) ABORT("file substr wrong"); if (strcmp(CORD_to_char_star(CORD_substr(w, 1000*36, 36)), y) != 0) ABORT("char * file substr wrong"); if (strcmp(CORD_substr(w, 1000*36, 2), "ab") != 0) ABORT("short file substr wrong"); if (CORD_str(x,1,"9a") != 35) ABORT("CORD_str failed 1"); if (CORD_str(x,0,"9abcdefghijk") != 35) ABORT("CORD_str failed 2"); if (CORD_str(x,0,"9abcdefghijx") != CORD_NOT_FOUND) ABORT("CORD_str failed 3"); if (CORD_str(x,0,"9>") != CORD_NOT_FOUND) ABORT("CORD_str failed 4"); if (remove(FNAME1) != 0) { /* On some systems, e.g. OS2, this may fail if f1 is still open. */ if ((fclose(f1a) == EOF) & (fclose(f1b) == EOF)) ABORT("fclose(f1) failed"); if (remove(FNAME1) != 0) ABORT("remove 1 failed"); } if (remove(FNAME2) != 0) { if (fclose(f2) == EOF) ABORT("fclose(f2) failed"); if (remove(FNAME2) != 0) ABORT("remove 2 failed"); } }
void test_extras() { # if defined(__OS2__) # define FNAME1 "tmp1" # define FNAME2 "tmp2" # elif defined(AMIGA) # define FNAME1 "T:tmp1" # define FNAME2 "T:tmp2" # else # define FNAME1 "/tmp/cord_test" # define FNAME2 "/tmp/cord_test2" # endif register int i; CORD y = "abcdefghijklmnopqrstuvwxyz0123456789"; CORD x = "{}"; CORD w, z; FILE *f; FILE *f1a, *f1b, *f2; w = CORD_cat(CORD_cat(y,y),y); z = CORD_catn(3,y,y,y); if (CORD_cmp(w,z) != 0) ABORT("CORD_catn comparison wrong"); for (i = 1; i < 100; i++) { x = CORD_cat(x, y); } z = CORD_balance(x); if (CORD_cmp(x,z) != 0) ABORT("balanced string comparison wrong"); if (CORD_cmp(x,CORD_cat(z, CORD_nul(13))) >= 0) ABORT("comparison 2"); if (CORD_cmp(CORD_cat(x, CORD_nul(13)), z) <= 0) ABORT("comparison 3"); if (CORD_cmp(x,CORD_cat(z, "13")) >= 0) ABORT("comparison 4"); if ((f = fopen(FNAME1, "w")) == 0) ABORT("open failed"); if (CORD_put(z,f) == EOF) ABORT("CORD_put failed"); if (fclose(f) == EOF) ABORT("fclose failed"); w = CORD_from_file(f1a = fopen(FNAME1, "rb")); if (CORD_len(w) != CORD_len(z)) ABORT("file length wrong"); if (CORD_cmp(w,z) != 0) ABORT("file comparison wrong"); if (CORD_cmp(CORD_substr(w, 50*36+2, 36), y) != 0) ABORT("file substr wrong"); z = CORD_from_file_lazy(f1b = fopen(FNAME1, "rb")); if (CORD_cmp(w,z) != 0) ABORT("File conversions differ"); if (CORD_chr(w, 0, '9') != 37) ABORT("CORD_chr failed 1"); if (CORD_chr(w, 3, 'a') != 38) ABORT("CORD_chr failed 2"); if (CORD_rchr(w, CORD_len(w) - 1, '}') != 1) ABORT("CORD_rchr failed"); x = y; for (i = 1; i < 14; i++) { x = CORD_cat(x,x); } if ((f = fopen(FNAME2, "w")) == 0) ABORT("2nd open failed"); if (CORD_put(x,f) == EOF) ABORT("CORD_put failed"); if (fclose(f) == EOF) ABORT("fclose failed"); w = CORD_from_file(f2 = fopen(FNAME2, "rb")); if (CORD_len(w) != CORD_len(x)) ABORT("file length wrong"); if (CORD_cmp(w,x) != 0) ABORT("file comparison wrong"); if (CORD_cmp(CORD_substr(w, 1000*36, 36), y) != 0) ABORT("file substr wrong"); if (strcmp(CORD_to_char_star(CORD_substr(w, 1000*36, 36)), y) != 0) ABORT("char * file substr wrong"); if (strcmp(CORD_substr(w, 1000*36, 2), "ab") != 0) ABORT("short file substr wrong"); if (CORD_str(x,1,"9a") != 35) ABORT("CORD_str failed 1"); if (CORD_str(x,0,"9abcdefghijk") != 35) ABORT("CORD_str failed 2"); if (CORD_str(x,0,"9abcdefghijx") != CORD_NOT_FOUND) ABORT("CORD_str failed 3"); if (CORD_str(x,0,"9>") != CORD_NOT_FOUND) ABORT("CORD_str failed 4"); if (remove(FNAME1) != 0) { /* On some systems, e.g. OS2, this may fail if f1 is still open. */ if ((fclose(f1a) == EOF) & (fclose(f1b) == EOF)) ABORT("fclose(f1) failed"); if (remove(FNAME1) != 0) ABORT("remove 1 failed"); } if (remove(FNAME2) != 0) { if (fclose(f2) == EOF) ABORT("fclose(f2) failed"); if (remove(FNAME2) != 0) ABORT("remove 2 failed"); } }
int main(int argc, char *argv[]) { CORD input = NULL; const char *in_file_name = NULL; FILE *in_file = NULL; Module *state = NULL; int opt; int disassemble = 0; const char *func = "main"; int interactive = 0; int listing = 0; while((opt = getopt(argc, argv, "lhdf:i")) != -1) { switch(opt) { case 'd': disassemble = 1; break; case 'f': func = optarg; break; case 'i': interactive = 1; break; case 'l': listing = 1; break; case 'h': /// fall through! default: die(NULL, "USAGE: earing [-d | -i] [-f function] <file.asm>\n"); return 1; } } if(optind >= argc) { die(NULL, "You have to give a file. Use -h to see the usage."); return 1; } GC_INIT(); in_file_name = argv[optind]; in_file = fopen(in_file_name, "r"); if(!in_file) { die(NULL, "Failed to open the input file %s", in_file_name); } input = CORD_from_file(in_file); state = Module_create(in_file_name, 1024); Module_register_default_directives(state); if(!Module_compile(state, CORD_to_const_char_star(input), CORD_len(input))) { die(state, "Parsing failed with %d errors.\n", state->errors); return 1; } else { if(listing) { tst_traverse(state->functions, (tst_traverse_cb)query_functions, NULL); } else if(disassemble) { dis_functions(state); } else if(interactive) { // go into interactive mode with the repl run_repl(state, in_file_name); } else { // run the given function or the "main" default run_function(state, func); } } return 0; }
void test_extras(void) { # define FNAME1 "cordtst1.tmp" /* short name (8+3) for portability */ # define FNAME2 "cordtst2.tmp" register int i; CORD y = "abcdefghijklmnopqrstuvwxyz0123456789"; CORD x = "{}"; CORD w, z; FILE *f; FILE *f1a, *f1b, *f2; w = CORD_cat(CORD_cat(y,y),y); z = CORD_catn(3,y,y,y); if (CORD_cmp(w,z) != 0) ABORT("CORD_catn comparison wrong"); for (i = 1; i < 100; i++) { x = CORD_cat(x, y); } z = CORD_balance(x); if (CORD_cmp(x,z) != 0) ABORT("balanced string comparison wrong"); if (CORD_cmp(x,CORD_cat(z, CORD_nul(13))) >= 0) ABORT("comparison 2"); if (CORD_cmp(CORD_cat(x, CORD_nul(13)), z) <= 0) ABORT("comparison 3"); if (CORD_cmp(x,CORD_cat(z, "13")) >= 0) ABORT("comparison 4"); if ((f = fopen(FNAME1, "w")) == 0) ABORT("open failed"); if (CORD_put(z,f) == EOF) ABORT("CORD_put failed"); if (fclose(f) == EOF) ABORT("fclose failed"); f1a = fopen(FNAME1, "rb"); if (!f1a) ABORT("Unable to open " FNAME1); w = CORD_from_file(f1a); if (CORD_len(w) != CORD_len(z)) ABORT("file length wrong"); if (CORD_cmp(w,z) != 0) ABORT("file comparison wrong"); if (CORD_cmp(CORD_substr(w, 50*36+2, 36), y) != 0) ABORT("file substr wrong"); f1b = fopen(FNAME1, "rb"); if (!f1b) ABORT("2nd open failed: " FNAME1); z = CORD_from_file_lazy(f1b); if (CORD_cmp(w,z) != 0) ABORT("File conversions differ"); if (CORD_chr(w, 0, '9') != 37) ABORT("CORD_chr failed 1"); if (CORD_chr(w, 3, 'a') != 38) ABORT("CORD_chr failed 2"); if (CORD_rchr(w, CORD_len(w) - 1, '}') != 1) ABORT("CORD_rchr failed"); x = y; for (i = 1; i < 14; i++) { x = CORD_cat(x,x); } if ((f = fopen(FNAME2, "w")) == 0) ABORT("2nd open failed"); # ifdef __DJGPP__ /* FIXME: DJGPP workaround. Why does this help? */ if (fflush(f) != 0) ABORT("fflush failed"); # endif if (CORD_put(x,f) == EOF) ABORT("CORD_put failed"); if (fclose(f) == EOF) ABORT("fclose failed"); f2 = fopen(FNAME2, "rb"); if (!f2) ABORT("Unable to open " FNAME2); w = CORD_from_file(f2); if (CORD_len(w) != CORD_len(x)) ABORT("file length wrong"); if (CORD_cmp(w,x) != 0) ABORT("file comparison wrong"); if (CORD_cmp(CORD_substr(w, 1000*36, 36), y) != 0) ABORT("file substr wrong"); if (strcmp(CORD_to_char_star(CORD_substr(w, 1000*36, 36)), y) != 0) ABORT("char * file substr wrong"); if (strcmp(CORD_substr(w, 1000*36, 2), "ab") != 0) ABORT("short file substr wrong"); if (CORD_str(x,1,"9a") != 35) ABORT("CORD_str failed 1"); if (CORD_str(x,0,"9abcdefghijk") != 35) ABORT("CORD_str failed 2"); if (CORD_str(x,0,"9abcdefghijx") != CORD_NOT_FOUND) ABORT("CORD_str failed 3"); if (CORD_str(x,0,"9>") != CORD_NOT_FOUND) ABORT("CORD_str failed 4"); /* Note: f1a, f1b, f2 handles are closed lazily by CORD library. */ /* TODO: Propose and use CORD_fclose. */ *(CORD volatile *)&w = CORD_EMPTY; *(CORD volatile *)&z = CORD_EMPTY; GC_gcollect(); GC_invoke_finalizers(); /* Of course, this does not guarantee the files are closed. */ if (remove(FNAME1) != 0) { /* On some systems, e.g. OS2, this may fail if f1 is still open. */ /* But we cannot call fclose as it might lead to double close. */ fprintf(stderr, "WARNING: remove(FNAME1) failed\n"); } if (remove(FNAME2) != 0) { fprintf(stderr, "WARNING: remove(FNAME2) failed\n"); } }