GC gc_cache_lookup(struct gc_cache *cache, XGCValues * gcv, unsigned long mask) { struct gc_cache_cell *cell = NULL, *next = NULL, *prev = NULL; struct gcv_and_mask gcvm; if (cache == NULL) abort(); else if ((!!cache->head) != (!!cache->tail)) abort(); else if (cache->head && cache->tail && (cache->head->prev || cache->tail->next)) abort(); else { gcvm.mask = mask; gcvm.gcv = *gcv; /* this copies... */ #ifdef GCCACHE_HASH if (gethash(&gcvm, cache->table, (const void **)((void*)&cell))) #else /* !GCCACHE_HASH */ /* start at the end (most recently used) */ cell = cache->tail; while (cell) { if (gc_cache_eql(&gcvm, &cell->gcvm)) break; else cell = cell->prev; } /* #### This whole file needs some serious overhauling. */ if (!(mask | GCTile) && cell->gc->values.tile) cell = NULL; else if (!(mask | GCStipple) && cell->gc->values.stipple) cell = NULL; #endif /* !GCCACHE_HASH */ { /* Found a cell. Move this cell to the end of the list, so that it will be less likely to be collected than a cell that was accessed less recently. */ if (!cell) { abort(); return NULL; } else { if (cell == cache->tail) return cell->gc; next = cell->next; prev = cell->prev; if (prev) prev->next = next; if (next) next->prev = prev; if (cache->head == cell) cache->head = next; cell->next = NULL; cell->prev = cache->tail; if (cache->tail) cache->tail->next = cell; else abort(); cache->tail = cell; if (cache->head == cell) abort(); else if (cell->next) abort(); else if (cache->head != NULL && cache->head->prev) abort(); else if (cache->tail != NULL && cache->tail->next) abort(); return cell->gc; } } /* else, cache miss. */ if (cache == NULL) abort(); else if (cache->size == GC_CACHE_SIZE) /* Reuse the first cell on the list (least-recently-used). Remove it from the list, and unhash it from the table. */ { cell = cache->head; if (cache->head != NULL) { cache->head = cell->next; cache->head->prev = 0; } if (cache->tail == cell) cache->tail = 0; /* only one */ XFreeGC(cache->dpy, cell->gc); cache->delete_count++; #ifdef GCCACHE_HASH remhash(&cell->gcvm, cache->table); #endif } else if (cache->size > GC_CACHE_SIZE) abort(); else { /* Allocate a new cell (don't put it in the list or table yet). */ cell = xnew(struct gc_cache_cell); cache->size++; } if (cell != NULL) { /* Now we've got a cell (new or reused). Fill it in. */ memcpy(&cell->gcvm.gcv, gcv, sizeof(XGCValues)); cell->gcvm.mask = mask; /* Put the cell on the end of the list. */ cell->next = 0; cell->prev = cache->tail; if (cache->tail) cache->tail->next = cell; cache->tail = cell; if (!cache->head) cache->head = cell; cache->create_count++; #ifdef GCCACHE_HASH /* Hash it in the table */ puthash(&cell->gcvm, cell, cache->table); #endif /* Now make and return the GC. */ cell->gc = XCreateGC(cache->dpy, cache->window, mask, gcv); /* debug */ assert(cell->gc == gc_cache_lookup(cache, gcv, mask)); return cell->gc; } } return NULL; /* No cell determined */ }
static void check_free (void *ptr) { __free_hook = 0; __malloc_hook = 0; if (!pointer_table) pointer_table = make_hash_table (max (100, FREE_QUEUE_LIMIT * 2)); if (ptr != 0) { long size; #ifdef UNMAPPED_FREE unsigned long rounded_up_size; #endif EMACS_INT present = (EMACS_INT) gethash (ptr, pointer_table, (const void **) (void *) &size); if (!present) { /* This can only happen if you try to free something that didn't come from malloc */ #if !defined(__linux__) /* I originally wrote: "There's really no need to drop core." I have seen the error of my ways. -slb */ assert (!strict_free_check); #endif printf("Freeing unmalloc'ed memory at %p\n", ptr); __free_hook = check_free; __malloc_hook = check_malloc; goto end; } if (size < 0) { /* This happens when you free twice */ #if !defined(__linux__) /* See above comment. */ assert (!strict_free_check); #endif printf("Freeing %p twice\n", ptr); __free_hook = check_free; __malloc_hook = check_malloc; goto end; } puthash (ptr, (void *)-size, pointer_table); #ifdef UNMAPPED_FREE /* Round up size to an even number of pages. */ rounded_up_size = ROUND_UP_TO_PAGE (size); /* Protect the pages freed from all access */ if (strict_free_check) mprotect (ptr, rounded_up_size, PROT_NONE); #else /* Set every word in the block to 0xDEADBEEF */ if (strict_free_check) { unsigned long long_length = (size + (sizeof (long) - 1)) / sizeof (long); unsigned long i; /* Not using the DEADBEEF_CONSTANT #define, since we don't know * that allocation sizes will be multiples of eight. */ for (i = 0; i < long_length; i++) ((unsigned long *) ptr)[i] = 0xDEADBEEF; } #endif free_queue[current_free].address = ptr; free_queue[current_free].length = size; current_free++; if (current_free >= FREE_QUEUE_LIMIT) current_free = 0; /* Really free this if there's something there */ { void *old = free_queue[current_free].address; if (old) { #ifdef UNMAPPED_FREE unsigned long old_len = free_queue[current_free].length; mprotect (old, old_len, PROT_READ | PROT_WRITE | PROT_EXEC); #endif free (old); remhash (old, pointer_table); } } } __free_hook = check_free; __malloc_hook = check_malloc; end: return; }
MYBOOL __WINAPI read_params(lprec *lp, char *filename, char *options) { int ret, looping, line; FILE *fp; hashtable *hashfunctions, *hashparameters; hashelem *hp; int i, j, elements, n, intvalue, state = 0; REAL REALvalue; char buf[4096], *header = NULL, *ptr, *ptr1, *ptr2; if((fp = ini_open(filename)) == NULL) ret = FALSE; else { /* create hashtable of all callable commands to find them quickly */ hashfunctions = create_hash_table(sizeof(functions) / sizeof(*functions), 0); for (n = 0, i = 0; i < (int) (sizeof(functions)/sizeof(*functions)); i++) { puthash(functions[i].par, i, NULL, hashfunctions); if(functions[i].values != NULL) n += functions[i].elements; } /* create hashtable of all arguments to find them quickly */ hashparameters = create_hash_table(n, 0); for (n = 0, i = 0; i < (int) (sizeof(functions)/sizeof(*functions)); i++) { if(functions[i].values != NULL) { elements = functions[i].elements; for(j = 0; j < elements; j++) if((strcmp(functions[i].values[j].svalue, "0") != 0) && (strcmp(functions[i].values[j].svalue, "1") != 0)) puthash(functions[i].values[j].svalue, j, NULL, hashparameters); } } readoptions(options, &header); STRUPR(header); ret = looping = TRUE; line = 0; while((ret) && (looping)) { line++; switch(ini_readdata(fp, buf, sizeof(buf), FALSE)) { case 0: /* End of file */ looping = FALSE; break; case 1: /* header */ switch(state) { case 0: STRUPR(buf); if(strcmp(buf, header) == 0) state = 1; break; case 1: looping = FALSE; break; } break; case 2: /* data */ if(state == 1) { for(ptr = buf; (*ptr) && (isspace(*ptr)); ptr++); } else ptr = NULL; if((ptr != NULL) && (*ptr)) { STRUPR(buf); ptr = strchr(buf, '='); if(ptr == NULL) { report(lp, IMPORTANT, "read_params: No equal sign on line %d\n", line); ret = FALSE; } else { *ptr = 0; for(ptr1 = buf; isspace(*ptr1); ptr1++); for(ptr2 = ptr - 1; (ptr2 >= ptr1) && (isspace(*ptr2)); ptr2--); if(ptr2 <= ptr1) { report(lp, IMPORTANT, "read_params: No parameter name before equal sign on line %d\n", line); ret = FALSE; } else { ptr2[1] = 0; hp = findhash(ptr1, hashfunctions); if(hp == NULL) { report(lp, IMPORTANT, "read_params: Unknown parameter name (%s) before equal sign on line %d\n", ptr1, line); ret = FALSE; } else { i = hp->index; ptr1 = ++ptr; intvalue = 0; REALvalue = 0; if(functions[i].values == NULL) { switch(functions[i].type) { case intfunction: case longfunction: case MYBOOLfunction: intvalue = strtol(ptr1, &ptr2, 10); while((*ptr2) && (isspace(*ptr2))) ptr2++; if(*ptr2) { report(lp, IMPORTANT, "read_params: Invalid integer value on line %d\n", line); ret = FALSE; } break; case REALfunction: REALvalue = strtod(ptr1, &ptr2); while((*ptr2) && (isspace(*ptr2))) ptr2++; if(*ptr2) { report(lp, IMPORTANT, "read_params: Invalid real value on line %d\n", line); ret = FALSE; } break; } } else { while(ret) { ptr = strchr(ptr1, '+'); if(ptr == NULL) ptr = ptr1 + strlen(ptr1); for(; isspace(*ptr1); ptr1++); for(ptr2 = ptr - 1; (ptr2 >= ptr1) && (isspace(*ptr2)); ptr2--); if(ptr2 <= ptr1) break; else { ptr2[1] = 0; hp = findhash(ptr1, hashparameters); if (hp == NULL) { report(lp, IMPORTANT, "read_params: Invalid parameter name (%s) on line %d\n", ptr1, line); ret = FALSE; } else { j = hp->index; if((j >= functions[i].elements) || (strcmp(functions[i].values[j].svalue, ptr1))) { report(lp, IMPORTANT, "read_params: Inappropriate parameter name (%s) on line %d\n", ptr1, line); ret = FALSE; } else { intvalue += functions[i].values[j].value; } } ptr1 = ptr + 1; } } } if(ret) { switch(functions[i].type) { case intfunction: functions[i].set_function.int_set_function(lp, intvalue); break; case longfunction: functions[i].set_function.long_set_function(lp, intvalue); break; case MYBOOLfunction: functions[i].set_function.MYBOOL_set_function(lp, (MYBOOL) intvalue); break; case REALfunction: functions[i].set_function.REAL_set_function(lp, REALvalue); break; } } } } } } break; } } FREE(header); free_hash_table(hashfunctions); free_hash_table(hashparameters); ini_close(fp); } return( (MYBOOL) ret ); }