VPR-6.0
|
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
Go to the source code of this file.
Data Structures | |
struct | s_linked_vptr |
struct | s_linked_int |
struct | s_ivec |
Defines | |
#define | INP |
#define | OUTP |
#define | INOUTP |
#define | ERRTAG "ERROR:\t" |
#define | WARNTAG "WARN:\t" |
#define | BUFSIZE 65536 |
#define | max(a, b) (((a) > (b))? (a) : (b)) |
#define | min(a, b) ((a) > (b)? (b) : (a)) |
#define | nint(a) ((int) floor (a + 0.5)) |
Typedefs | |
typedef struct s_linked_int | t_linked_int |
typedef struct s_ivec | t_ivec |
Enumerations | |
enum | boolean { FALSE, TRUE } |
Functions | |
int | limit_value (int cur, int max, const char *name) |
void * | my_malloc (size_t size) |
void * | my_calloc (size_t nelem, size_t size) |
void * | my_realloc (void *ptr, size_t size) |
void * | my_chunk_malloc (size_t size, struct s_linked_vptr **chunk_ptr_head, int *mem_avail_ptr, char **next_mem_loc_ptr) |
void | free_chunk_memory (struct s_linked_vptr *chunk_ptr_head) |
void | free_ivec_vector (struct s_ivec *ivec_vector, int nrmin, int nrmax) |
void | free_ivec_matrix (struct s_ivec **ivec_matrix, int nrmin, int nrmax, int ncmin, int ncmax) |
void | free_ivec_matrix3 (struct s_ivec ***ivec_matrix3, int nrmin, int nrmax, int ncmin, int ncmax, int ndmin, int ndmax) |
void ** | alloc_matrix (int nrmin, int nrmax, int ncmin, int ncmax, size_t elsize) |
void *** | alloc_matrix3 (int nrmin, int nrmax, int ncmin, int ncmax, int ndmin, int ndmax, size_t elsize) |
void **** | alloc_matrix4 (int nrmin, int nrmax, int ncmin, int ncmax, int ndmin, int ndmax, int nemin, int nemax, size_t elsize) |
void | free_matrix (void *vptr, int nrmin, int nrmax, int ncmin, size_t elsize) |
void | free_matrix3 (void *vptr, int nrmin, int nrmax, int ncmin, int ncmax, int ndmin, size_t elsize) |
void | free_matrix4 (void *vptr, int nrmin, int nrmax, int ncmin, int ncmax, int ndmin, int ndmax, int nemin, size_t elsize) |
void | print_int_matrix3 (int ***vptr, int nrmin, int nrmax, int ncmin, int ncmax, int ndmin, int ndmax, char *file) |
struct s_linked_vptr * | insert_in_vptr_list (struct s_linked_vptr *head, void *vptr_to_add) |
struct s_linked_vptr * | delete_in_vptr_list (struct s_linked_vptr *head) |
t_linked_int * | insert_in_int_list (t_linked_int *head, int data, t_linked_int **free_list_head_ptr) |
void | free_int_list (t_linked_int **int_list_head_ptr) |
void | alloc_ivector_and_copy_int_list (t_linked_int **list_head_ptr, int num_items, struct s_ivec *ivec, t_linked_int **free_list_head_ptr) |
int | my_atoi (const char *str) |
char * | my_strdup (const char *str) |
char * | my_strncpy (char *dest, const char *src, size_t size) |
char * | my_strtok (char *ptr, char *tokens, FILE *fp, char *buf) |
FILE * | my_fopen (const char *fname, const char *flag, int prompt) |
char * | my_fgets (char *buf, int max_size, FILE *fp) |
void | my_srandom (int seed) |
int | my_irand (int imax) |
float | my_frand (void) |
Variables | |
int | linenum |
#define BUFSIZE 65536 |
Integer vector. nelem stores length, list[0..nelem-1] stores list of integers.
typedef struct s_linked_int t_linked_int |
Linked lists of integers.
void alloc_ivector_and_copy_int_list | ( | t_linked_int ** | list_head_ptr, |
int | num_items, | ||
struct s_ivec * | ivec, | ||
t_linked_int ** | free_list_head_ptr | ||
) |
Allocates an integer vector with num_items elements and copies the integers from the list pointed to by list_head (of which there must be num_items) over to it. The int_list is then put on the free list, and the list_head_ptr is set to NULL.
Definition at line 391 of file util.c.
{ t_linked_int *linked_int, *list_head; int i, *list; list_head = *list_head_ptr; if(num_items == 0) { /* Empty list. */ ivec->nelem = 0; ivec->list = NULL; if(list_head != NULL) { printf(ERRTAG "alloc_ivector_and_copy_int_list: Copied %d elements, " "but list at %p contains more.\n", num_items, (void *)list_head); exit(1); } return; } ivec->nelem = num_items; list = (int *)my_malloc(num_items * sizeof(int)); ivec->list = list; linked_int = list_head; for(i = 0; i < num_items - 1; i++) { list[i] = linked_int->data; linked_int = linked_int->next; } list[num_items - 1] = linked_int->data; if(linked_int->next != NULL) { printf ("Error in alloc_ivector_and_copy_int_list:\n Copied %d elements, " "but list at %p contains more.\n", num_items, (void *)list_head); exit(1); } linked_int->next = *free_list_head_ptr; *free_list_head_ptr = list_head; *list_head_ptr = NULL; }
void** alloc_matrix | ( | int | nrmin, |
int | nrmax, | ||
int | ncmin, | ||
int | ncmax, | ||
size_t | elsize | ||
) |
allocates an generic matrix with nrmax-nrmin + 1 rows and ncmax - ncmin + 1 columns, with each element of size elsize. i.e. returns a pointer to a storage block [nrmin..nrmax][ncmin..ncmax]. Simply cast the returned array pointer to the proper type.
Definition at line 593 of file util.c.
{ int i; char **cptr; cptr = (char **)my_malloc((nrmax - nrmin + 1) * sizeof(char *)); cptr -= nrmin; for(i = nrmin; i <= nrmax; i++) { cptr[i] = (char *)my_malloc((ncmax - ncmin + 1) * elsize); cptr[i] -= ncmin * elsize / sizeof(char); /* sizeof(char) = 1 */ } return ((void **)cptr); }
void*** alloc_matrix3 | ( | int | nrmin, |
int | nrmax, | ||
int | ncmin, | ||
int | ncmax, | ||
int | ndmin, | ||
int | ndmax, | ||
size_t | elsize | ||
) |
allocates a 3D generic matrix with nrmax-nrmin + 1 rows, ncmax - ncmin + 1 columns, and a depth of ndmax-ndmin + 1, with each element of size elsize. i.e. returns a pointer to a storage block [nrmin..nrmax][ncmin..ncmax][ndmin..ndmax]. Simply cast the returned array pointer to the proper type.
Definition at line 632 of file util.c.
{ int i, j; char ***cptr; cptr = (char ***)my_malloc((nrmax - nrmin + 1) * sizeof(char **)); cptr -= nrmin; for(i = nrmin; i <= nrmax; i++) { cptr[i] = (char **)my_malloc((ncmax - ncmin + 1) * sizeof(char *)); cptr[i] -= ncmin; for(j = ncmin; j <= ncmax; j++) { cptr[i][j] = (char *)my_malloc((ndmax - ndmin + 1) * elsize); cptr[i][j] -= ndmin * elsize / sizeof(char); /* sizeof(char) = 1) */ } } return ((void ***)cptr); }
void**** alloc_matrix4 | ( | int | nrmin, |
int | nrmax, | ||
int | ncmin, | ||
int | ncmax, | ||
int | ndmin, | ||
int | ndmax, | ||
int | nemin, | ||
int | nemax, | ||
size_t | elsize | ||
) |
allocates a 3D generic matrix with nrmax-nrmin + 1 rows, ncmax - ncmin + 1 columns, and a depth of ndmax-ndmin + 1, with each element of size elsize. i.e. returns a pointer to a storage block [nrmin..nrmax][ncmin..ncmax][ndmin..ndmax]. Simply cast the returned array pointer to the proper type.
Definition at line 663 of file util.c.
{ int i, j, k; char ****cptr; cptr = (char ****)my_malloc((nrmax - nrmin + 1) * sizeof(char ***)); cptr -= nrmin; for(i = nrmin; i <= nrmax; i++) { cptr[i] = (char ***)my_malloc((ncmax - ncmin + 1) * sizeof(char **)); cptr[i] -= ncmin; for(j = ncmin; j <= ncmax; j++) { cptr[i][j] = (char **)my_malloc((ndmax - ndmin + 1) * sizeof(char *)); cptr[i][j] -= ndmin; for(k = ndmin; k <= ndmax; k++) { cptr[i][j][k] = (char *)my_malloc((nemax - nemin + 1) * elsize); cptr[i][j][k] -= nemin * elsize / sizeof(char); /* sizeof(char) = 1) */ } } } return ((void ****)cptr); }
struct s_linked_vptr* delete_in_vptr_list | ( | struct s_linked_vptr * | head | ) | [read] |
Deletes the element at the head of a linked list of void pointers. Returns the new head of the list.
Definition at line 326 of file util.c.
{ struct s_linked_vptr *linked_vptr; if (head == NULL) return NULL; linked_vptr = head->next; free(head); return linked_vptr; /* New head of the list */ }
void free_chunk_memory | ( | struct s_linked_vptr * | chunk_ptr_head | ) |
Frees the memory allocated by a sequence of calls to my_chunk_malloc.
Definition at line 290 of file util.c.
{ struct s_linked_vptr *curr_ptr, *prev_ptr; curr_ptr = chunk_ptr_head; while(curr_ptr != NULL) { free(curr_ptr->data_vptr); /* Free memory "chunk". */ prev_ptr = curr_ptr; curr_ptr = curr_ptr->next; free(prev_ptr); /* Free memory used to track "chunk". */ } }
void free_int_list | ( | t_linked_int ** | int_list_head_ptr | ) |
This routine truly frees (calls free) all the integer list elements on the linked list pointed to by *head, and sets head = NULL.
Definition at line 368 of file util.c.
{ t_linked_int *linked_int, *next_linked_int; linked_int = *int_list_head_ptr; while(linked_int != NULL) { next_linked_int = linked_int->next; free(linked_int); linked_int = next_linked_int; } *int_list_head_ptr = NULL; }
void free_ivec_matrix | ( | struct s_ivec ** | ivec_matrix, |
int | nrmin, | ||
int | nrmax, | ||
int | ncmin, | ||
int | ncmax | ||
) |
Frees a 2D matrix of integer vectors (ivecs).
Definition at line 543 of file util.c.
{ int i, j; for(i = nrmin; i <= nrmax; i++) { for(j = ncmin; j <= ncmax; j++) { if(ivec_matrix[i][j].nelem != 0) { free(ivec_matrix[i][j].list); } } } free_matrix(ivec_matrix, nrmin, nrmax, ncmin, sizeof(struct s_ivec)); }
void free_ivec_matrix3 | ( | struct s_ivec *** | ivec_matrix3, |
int | nrmin, | ||
int | nrmax, | ||
int | ncmin, | ||
int | ncmax, | ||
int | ndmin, | ||
int | ndmax | ||
) |
Frees a 3D matrix of integer vectors (ivecs).
Definition at line 564 of file util.c.
{ int i, j, k; for(i = nrmin; i <= nrmax; i++) { for(j = ncmin; j <= ncmax; j++) { for(k = ndmin; k <= ndmax; k++) { if(ivec_matrix3[i][j][k].nelem != 0) { free(ivec_matrix3[i][j][k].list); } } } } free_matrix3(ivec_matrix3, nrmin, nrmax, ncmin, ncmax, ndmin, sizeof(struct s_ivec)); }
void free_ivec_vector | ( | struct s_ivec * | ivec_vector, |
int | nrmin, | ||
int | nrmax | ||
) |
void free_matrix | ( | void * | vptr, |
int | nrmin, | ||
int | nrmax, | ||
int | ncmin, | ||
size_t | elsize | ||
) |
void free_matrix3 | ( | void * | vptr, |
int | nrmin, | ||
int | nrmax, | ||
int | ncmin, | ||
int | ncmax, | ||
int | ndmin, | ||
size_t | elsize | ||
) |
void free_matrix4 | ( | void * | vptr, |
int | nrmin, | ||
int | nrmax, | ||
int | ncmin, | ||
int | ncmax, | ||
int | ndmin, | ||
int | ndmax, | ||
int | nemin, | ||
size_t | elsize | ||
) |
Definition at line 740 of file util.c.
{ int i, j, k; char ****cptr; cptr = (char ****)vptr; for(i = nrmin; i <= nrmax; i++) { for(j = ncmin; j <= ncmax; j++) { for(k = ndmin; k <= ndmax; k++) free(cptr[i][j][k] + nemin * elsize / sizeof(char)); free(cptr[i][j] + ndmin * elsize / sizeof(char)); } free(cptr[i] + ncmin); } free(cptr + nrmin); }
t_linked_int* insert_in_int_list | ( | t_linked_int * | head, |
int | data, | ||
t_linked_int ** | free_list_head_ptr | ||
) |
Inserts a new element at the head of a linked list of integers. Returns the new head of the list. One argument is the address of the head of a list of free ilist elements. If there are any elements on this free list, the new element is taken from it. Otherwise a new one is malloced.
Definition at line 343 of file util.c.
{ t_linked_int *linked_int; if(*free_list_head_ptr != NULL) { linked_int = *free_list_head_ptr; *free_list_head_ptr = linked_int->next; } else { linked_int = (t_linked_int *) my_malloc(sizeof(t_linked_int)); } linked_int->data = data; linked_int->next = head; return (linked_int); }
struct s_linked_vptr* insert_in_vptr_list | ( | struct s_linked_vptr * | head, |
void * | vptr_to_add | ||
) | [read] |
Inserts a new element at the head of a linked list of void pointers. Returns the new head of the list.
Definition at line 309 of file util.c.
{ struct s_linked_vptr *linked_vptr; linked_vptr = (struct s_linked_vptr *)my_malloc(sizeof(struct s_linked_vptr)); linked_vptr->data_vptr = vptr_to_add; linked_vptr->next = head; return (linked_vptr); /* New head of the list */ }
int limit_value | ( | int | cur, |
int | max, | ||
const char * | name | ||
) |
int my_atoi | ( | const char * | str | ) |
Returns the integer represented by the first part of the character string.
Definition at line 120 of file util.c.
{ if(str[0] < '0' || str[0] > '9') { if(!(str[0] == '-' && str[1] >= '0' && str[1] <= '9')) { printf(ERRTAG "expected number instead of '%s'.\n", str); exit(1); } } return (atoi(str)); }
void* my_calloc | ( | size_t | nelem, |
size_t | size | ||
) |
void* my_chunk_malloc | ( | size_t | size, |
struct s_linked_vptr ** | chunk_ptr_head, | ||
int * | mem_avail_ptr, | ||
char ** | next_mem_loc_ptr | ||
) |
This routine should be used for allocating fairly small data structures where memory-efficiency is crucial. This routine allocates large "chunks" of data, and parcels them out as requested. Whenever it mallocs a new chunk it adds it to the linked list pointed to by chunk_ptr_head. This list can be used to free the chunked memory. If chunk_ptr_head is NULL, no list of chunked memory blocks will be kept -- this is useful for data structures that you never intend to free as it means you don't have to keep track of the linked lists. Information about the currently open "chunk" must be stored by the user program. mem_avail_ptr points to an int storing how many bytes are left in the current chunk, while next_mem_loc_ptr is the address of a pointer to the next free bytes in the chunk. To start a new chunk, simply set *mem_avail_ptr = 0. Each independent set of data structures should use a new chunk.
Definition at line 207 of file util.c.
{ /* To make sure the memory passed back is properly aligned, I must * * only send back chunks in multiples of the worst-case alignment * * restriction of the machine. On most machines this should be * * a long, but on 64-bit machines it might be a long long or a * * double. Change the typedef below if this is the case. */ typedef long Align; #define CHUNK_SIZE 32768 #define FRAGMENT_THRESHOLD 100 char *tmp_ptr; int aligned_size; assert(*mem_avail_ptr >= 0); if((size_t) (*mem_avail_ptr) < size) { /* Need to malloc more memory. */ if(size > CHUNK_SIZE) { /* Too big, use standard routine. */ tmp_ptr = my_malloc(size); /* When debugging, uncomment the code below to see if memory allocation size */ /* makes sense */ /*#ifdef DEBUG printf("NB: my_chunk_malloc got a request for %d bytes.\n", size); printf("You should consider using my_malloc for such big requests.\n"); #endif */ if(chunk_ptr_head != NULL) *chunk_ptr_head = insert_in_vptr_list(*chunk_ptr_head, tmp_ptr); return (tmp_ptr); } if(*mem_avail_ptr < FRAGMENT_THRESHOLD) { /* Only a small scrap left. */ *next_mem_loc_ptr = my_malloc(CHUNK_SIZE); *mem_avail_ptr = CHUNK_SIZE; if(chunk_ptr_head != NULL) *chunk_ptr_head = insert_in_vptr_list(*chunk_ptr_head, *next_mem_loc_ptr); } /* Execute else clause only when the chunk we want is pretty big, * * and would leave too big an unused fragment. Then we use malloc * * to allocate normally. */ else { tmp_ptr = my_malloc(size); if(chunk_ptr_head != NULL) *chunk_ptr_head = insert_in_vptr_list(*chunk_ptr_head, tmp_ptr); return (tmp_ptr); } } /* Find the smallest distance to advance the memory pointer and keep * * everything aligned. */ if(size % sizeof(Align) == 0) { aligned_size = size; } else { aligned_size = size + sizeof(Align) - size % sizeof(Align); } tmp_ptr = *next_mem_loc_ptr; *next_mem_loc_ptr += aligned_size; *mem_avail_ptr -= aligned_size; return (tmp_ptr); }
char* my_fgets | ( | char * | buf, |
int | max_size, | ||
FILE * | fp | ||
) |
Get an input line, update the line number and cut off any comment part. A \ at the end of a line with no comment part (#) means continue.
Definition at line 447 of file util.c.
{ char *val; int i; cont = 0; val = fgets(buf, max_size, fp); linenum++; if(val == NULL) return (val); /* Check that line completely fit into buffer. (Flags long line * * truncation). */ for(i = 0; i < max_size; i++) { if(buf[i] == '\n') break; if(buf[i] == '\0') { printf ("Error on line %d -- line is too long for input buffer.\n", linenum); printf("All lines must be at most %d characters long.\n", BUFSIZE - 2); printf ("The problem could also be caused by a missing newline.\n"); exit(1); } } for(i = 0; i < max_size && buf[i] != '\0'; i++) { if(buf[i] == '#') { buf[i] = '\0'; break; } } if(i < 2) return (val); if(buf[i - 1] == '\n' && buf[i - 2] == '\\') { cont = 1; /* line continued */ buf[i - 2] = '\n'; /* May need this for tokens */ buf[i - 1] = '\0'; } return (val); }
FILE* my_fopen | ( | const char * | fname, |
const char * | flag, | ||
int | prompt | ||
) |
Uses global var 'OutFilePrefix'
Definition at line 59 of file util.c.
{ FILE *fp; int Len; char *new_fname = NULL; char prompt_filename[256]; /* Appends a prefix string for output files */ if(OutFilePrefix) { if(strchr(flag, 'w')) { Len = 1; /* NULL char */ Len += strlen(OutFilePrefix); Len += strlen(fname); new_fname = (char *)my_malloc(Len * sizeof(char)); strcpy(new_fname, OutFilePrefix); strcat(new_fname, fname); fname = new_fname; } } if (prompt) { scanf("%s",prompt_filename); fname = prompt_filename; } if(NULL == (fp = fopen(fname, flag))) { printf("Error opening file %s for %s access.\n", fname, flag); exit(1); } if(new_fname) free(new_fname); return (fp); }
float my_frand | ( | void | ) |
Creates a random float between 0 and 1. i.e. [0..1).
Definition at line 807 of file util.c.
{ float fval; int ival; current_random = current_random * IA + IC; /* Use overflow to wrap */ ival = current_random & (IM - 1); /* Modulus */ fval = (float)ival / (float)IM; #ifdef CHECK_RAND if((fval < 0) || (fval > 1.)) { printf("Bad value in my_frand, fval = %g\n", fval); exit(1); } #endif return (fval); }
int my_irand | ( | int | imax | ) |
Creates a random integer between 0 and imax, inclusive. i.e. [0..imax]
Definition at line 779 of file util.c.
{ int ival; /* current_random = (current_random * IA + IC) % IM; */ current_random = current_random * IA + IC; /* Use overflow to wrap */ ival = current_random & (IM - 1); /* Modulus */ ival = (int)((float)ival * (float)(imax + 0.999) / (float)IM); #ifdef CHECK_RAND if((ival < 0) || (ival > imax)) { if(ival == imax + 1) { /* Due to random floating point rounding, sometimes above calculation gives number greater than ival by 1 */ ival = imax; } else { printf("Bad value in my_irand, imax = %d ival = %d\n", imax, ival); exit(1); } } #endif return (ival); }
void* my_malloc | ( | size_t | size | ) |
void* my_realloc | ( | void * | ptr, |
size_t | size | ||
) |
Definition at line 168 of file util.c.
{ void *ret; if(size <= 0) { printf("reallocating of size <= 0.\n"); } ret = realloc(ptr, size); if(NULL == ret) { printf(ERRTAG "Unable to realloc memory. Aborting. " "ptr=%p, Size=%d.\n", ptr, (int)size); if(ptr == NULL) { printf(ERRTAG "my_realloc: ptr == NULL. Aborting.\n"); } exit(1); } return (ret); }
void my_srandom | ( | int | seed | ) |
Definition at line 772 of file util.c.
{ current_random = (unsigned int)seed; }
char* my_strdup | ( | const char * | str | ) |
char* my_strncpy | ( | char * | dest, |
const char * | src, | ||
size_t | size | ||
) |
Definition at line 39 of file util.c.
{ /* Find string's length */ size_t len = strlen(src); /* Cap length at (num - 1) to leave room for \0 */ if(size <= len) len = (size - 1); /* Copy as much of string as we can fit */ memcpy(dest, src, len); /* explicit null termination */ dest[len] = '\0'; return dest; }
char* my_strtok | ( | char * | ptr, |
char * | tokens, | ||
FILE * | fp, | ||
char * | buf | ||
) |
Get next token, and wrap to next line if \ at end of line. There is a bit of a "gotcha" in strtok. It does not make a copy of the character array which you pass by pointer on the first call. Thus, you must make sure this array exists for as long as you are using strtok to parse that line. Don't use local buffers in a bunch of subroutines calling each other; the local buffer may be overwritten when the stack is restored after return from the subroutine.
Definition at line 509 of file util.c.
{ char *val; val = strtok(ptr, tokens); for(;;) { if(val != NULL || cont == 0) return (val); /* return unless we have a null value and a continuation line */ if(my_fgets(buf, BUFSIZE, fp) == NULL) return (NULL); val = strtok(buf, tokens); } }
void print_int_matrix3 | ( | int *** | vptr, |
int | nrmin, | ||
int | nrmax, | ||
int | ncmin, | ||
int | ncmax, | ||
int | ndmin, | ||
int | ndmax, | ||
char * | file | ||
) |
Definition at line 696 of file util.c.
{ FILE *outfile; int i, j, k; outfile = my_fopen(file, "w", 0); for(k = nrmin; k <= nrmax; ++k) { fprintf(outfile, "Plane %d\n", k); for(j = ncmin; j <= ncmax; ++j) { for(i = ndmin; i <= ndmax; ++i) { fprintf(outfile, "%d ", vptr[k][j][i]); } fprintf(outfile, "\n"); } fprintf(outfile, "\n"); } fclose(outfile); }