⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 util.c

📁 fpga设计评估软件
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <string.h>#include <stdio.h>#include <stdlib.h>#include "util.h"/* This file contains utility functions widely used in * * my programs.  Many are simply versions of file and  * * memory grabbing routines that take the same         * * arguments as the standard library ones, but exit    * * the program if they find an error condition.        */int linenum;  /* Line in file being parsed. */FILE *my_fopen (char *fname, char *flag, int prompt) { FILE *fp;   /* prompt = 1: prompt user.  prompt=0: use fname */ while (1) {    if (prompt)        scanf("%s",fname);    if ((fp = fopen(fname,flag)) != NULL)       break;     printf("Error opening file %s for %s access.\n",fname,flag);    if (!prompt)        exit(1);    printf("Please enter another filename.\n"); } return (fp);}int my_atoi (const char *str) {/* Returns the integer represented by the first part of the character       * * string.  Unlike the normal atoi, I return -1 if the string doesn't       * * start with a numeric digit.                                              */ if (str[0] < '0' || str[0] > '9')     return (-1); return (atoi(str));}void *my_calloc (size_t nelem, size_t size) { void *ret; if ((ret = calloc (nelem,size)) == NULL) {    fprintf(stderr,"Error:  Unable to calloc memory.  Aborting.\n");    exit (1); } return (ret);}void *my_malloc (size_t size) { void *ret; if ((ret = malloc (size)) == NULL) {    fprintf(stderr,"Error:  Unable to malloc memory.  Aborting.\n");    abort ();    exit (1); } return (ret);}void *my_realloc (void *ptr, size_t size) { void *ret; if ((ret = realloc (ptr,size)) == NULL) {    fprintf(stderr,"Error:  Unable to realloc memory.  Aborting.\n");    exit (1); } return (ret);}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.                                                  */ /* 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; if (*mem_avail_ptr < size) {       /* Need to malloc more memory. */    if (size > CHUNK_SIZE) {      /* Too big, use standard routine. */       tmp_ptr = my_malloc (size);/*#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);}void free_chunk_memory (struct s_linked_vptr *chunk_ptr_head) {/* Frees the memory allocated by a sequence of calls to my_chunk_malloc. */ 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". */ }}struct s_linked_vptr *insert_in_vptr_list (struct s_linked_vptr *head,              void *vptr_to_add) {/* Inserts a new element at the head of a linked list of void pointers. * * Returns the new head of the list.                                    */ 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 */}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. */ 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);}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.          */   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 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.                                        */ 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 ("Error in alloc_ivector_and_copy_int_list:\n Copied %d "           "elements, but list at %p contains more.\n", num_items, 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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -