?? cordxtra.c
字號:
/* * Copyright (c) 1993-1994 by Xerox Corporation. All rights reserved. * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. * * Permission is hereby granted to use or copy this program * for any purpose, provided the above notices are retained on all copies. * Permission to modify the code and to distribute modified code is granted, * provided the above notices are retained, and a notice that the code was * modified is included with the above copyright notice. * * Author: Hans-J. Boehm (boehm@parc.xerox.com) *//* * These are functions on cords that do not need to understand their * implementation. They serve also serve as example client code for * cord_basics. *//* Boehm, December 8, 1995 1:53 pm PST */# include <stdio.h># include <string.h># include <stdlib.h># include <stdarg.h># include "cord.h"# include "ec.h"# define I_HIDE_POINTERS /* So we get access to allocation lock. */ /* We use this for lazy file reading, */ /* so that we remain independent */ /* of the threads primitives. */# include "gc.h"/* For now we assume that pointer reads and writes are atomic, *//* i.e. another thread always sees the state before or after *//* a write. This might be false on a Motorola M68K with *//* pointers that are not 32-bit aligned. But there probably *//* aren't too many threads packages running on those. */# define ATOMIC_WRITE(x,y) (x) = (y)# define ATOMIC_READ(x) (*(x))/* The standard says these are in stdio.h, but they aren't always: */# ifndef SEEK_SET# define SEEK_SET 0# endif# ifndef SEEK_END# define SEEK_END 2# endif# define BUFSZ 2048 /* Size of stack allocated buffers when */ /* we want large buffers. */typedef void (* oom_fn)(void);# define OUT_OF_MEMORY { if (CORD_oom_fn != (oom_fn) 0) (*CORD_oom_fn)(); \ ABORT("Out of memory\n"); }# define ABORT(msg) { fprintf(stderr, "%s\n", msg); abort(); }CORD CORD_cat_char(CORD x, char c){ register char * string; if (c == '\0') return(CORD_cat(x, CORD_nul(1))); string = GC_MALLOC_ATOMIC(2); if (string == 0) OUT_OF_MEMORY; string[0] = c; string[1] = '\0'; return(CORD_cat_char_star(x, string, 1));}CORD CORD_catn(int nargs, ...){ register CORD result = CORD_EMPTY; va_list args; register int i; va_start(args, nargs); for (i = 0; i < nargs; i++) { register CORD next = va_arg(args, CORD); result = CORD_cat(result, next); } va_end(args); return(result);}typedef struct { size_t len; size_t count; char * buf;} CORD_fill_data;int CORD_fill_proc(char c, void * client_data){ register CORD_fill_data * d = (CORD_fill_data *)client_data; register size_t count = d -> count; (d -> buf)[count] = c; d -> count = ++count; if (count >= d -> len) { return(1); } else { return(0); }}int CORD_batched_fill_proc(const char * s, void * client_data){ register CORD_fill_data * d = (CORD_fill_data *)client_data; register size_t count = d -> count; register size_t max = d -> len; register char * buf = d -> buf; register const char * t = s; while((buf[count] = *t++) != '\0') { count++; if (count >= max) { d -> count = count; return(1); } } d -> count = count; return(0);}/* Fill buf with len characters starting at i. *//* Assumes len characters are available. */ void CORD_fill_buf(CORD x, size_t i, size_t len, char * buf){ CORD_fill_data fd; fd.len = len; fd.buf = buf; fd.count = 0; (void)CORD_iter5(x, i, CORD_fill_proc, CORD_batched_fill_proc, &fd);}int CORD_cmp(CORD x, CORD y){ CORD_pos xpos; CORD_pos ypos; register size_t avail, yavail; if (y == CORD_EMPTY) return(x != CORD_EMPTY); if (x == CORD_EMPTY) return(-1); if (CORD_IS_STRING(y) && CORD_IS_STRING(x)) return(strcmp(x,y)); CORD_set_pos(xpos, x, 0); CORD_set_pos(ypos, y, 0); for(;;) { if (!CORD_pos_valid(xpos)) { if (CORD_pos_valid(ypos)) { return(-1); } else { return(0); } } if (!CORD_pos_valid(ypos)) { return(1); } if ((avail = CORD_pos_chars_left(xpos)) <= 0 || (yavail = CORD_pos_chars_left(ypos)) <= 0) { register char xcurrent = CORD_pos_fetch(xpos); register char ycurrent = CORD_pos_fetch(ypos); if (xcurrent != ycurrent) return(xcurrent - ycurrent); CORD_next(xpos); CORD_next(ypos); } else { /* process as many characters as we can */ register int result; if (avail > yavail) avail = yavail; result = strncmp(CORD_pos_cur_char_addr(xpos), CORD_pos_cur_char_addr(ypos), avail); if (result != 0) return(result); CORD_pos_advance(xpos, avail); CORD_pos_advance(ypos, avail); } }}int CORD_ncmp(CORD x, size_t x_start, CORD y, size_t y_start, size_t len){ CORD_pos xpos; CORD_pos ypos; register size_t count; register long avail, yavail; CORD_set_pos(xpos, x, x_start); CORD_set_pos(ypos, y, y_start); for(count = 0; count < len;) { if (!CORD_pos_valid(xpos)) { if (CORD_pos_valid(ypos)) { return(-1); } else { return(0); } } if (!CORD_pos_valid(ypos)) { return(1); } if ((avail = CORD_pos_chars_left(xpos)) <= 0 || (yavail = CORD_pos_chars_left(ypos)) <= 0) { register char xcurrent = CORD_pos_fetch(xpos); register char ycurrent = CORD_pos_fetch(ypos); if (xcurrent != ycurrent) return(xcurrent - ycurrent); CORD_next(xpos); CORD_next(ypos); count++; } else { /* process as many characters as we can */ register int result; if (avail > yavail) avail = yavail; count += avail; if (count > len) avail -= (count - len); result = strncmp(CORD_pos_cur_char_addr(xpos), CORD_pos_cur_char_addr(ypos), (size_t)avail); if (result != 0) return(result); CORD_pos_advance(xpos, (size_t)avail); CORD_pos_advance(ypos, (size_t)avail); } } return(0);}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);}CORD CORD_from_char_star(const char *s){ char * result; size_t len = strlen(s); if (0 == len) return(CORD_EMPTY); result = GC_MALLOC_ATOMIC(len + 1); if (result == 0) OUT_OF_MEMORY; memcpy(result, s, len+1); return(result);}const char * CORD_to_const_char_star(CORD x){ if (x == 0) return(""); if (CORD_IS_STRING(x)) return((const char *)x); return(CORD_to_char_star(x));}char CORD_fetch(CORD x, size_t i){ CORD_pos xpos; CORD_set_pos(xpos, x, i); if (!CORD_pos_valid(xpos)) ABORT("bad index?"); return(CORD_pos_fetch(xpos));}int CORD_put_proc(char c, void * client_data){ register FILE * f = (FILE *)client_data; return(putc(c, f) == EOF);}int CORD_batched_put_proc(const char * s, void * client_data){ register FILE * f = (FILE *)client_data; return(fputs(s, f) == EOF);} int CORD_put(CORD x, FILE * f){ if (CORD_iter5(x, 0, CORD_put_proc, CORD_batched_put_proc, f)) { return(EOF); } else { return(1); }}typedef struct { size_t pos; /* Current position in the cord */ char target; /* Character we're looking for */} chr_data;int CORD_chr_proc(char c, void * client_data){ register chr_data * d = (chr_data *)client_data; if (c == d -> target) return(1); (d -> pos) ++; return(0);}int CORD_rchr_proc(char c, void * client_data){ register chr_data * d = (chr_data *)client_data; if (c == d -> target) return(1); (d -> pos) --; return(0);}int CORD_batched_chr_proc(const char *s, void * client_data)
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -