· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
obsutil

If you click on the title of a category page, you'll get a list of pages belonging to that category

관련된 모든 페이지의 목록을 보려면 제목을 누르세요.

TODO: 아직 완전히 쓴 문서는 아닙니다. 수정하기 전에 CCodeSnippets를 읽어 주시기 바랍니다.

obsutil.h

/* $Id: obsutil,v 1.2 2004/12/05 01:15:02 kss Exp kss $ */
/*
 * GNU obstack wrapper with some utilities
 * Copyright (C) 2003, 2004  Seong-Kook Shin <cinsk.shin at samsung.com>
 */
#ifndef OBSUTIL_H_
#define OBSUTIL_H_
                                                                                
#if HAVE_CONFIG_H
# include <config.h>
#endif
                                                                                
#include <obstack.h>
                                                                                
#ifndef obstack_chunk_alloc
# include <stdlib.h>
# define obstack_chunk_alloc     malloc
# define obstack_chunk_free      free
#endif
                                                                                
/* This indirect using of extern "C" { ... } makes Emacs happy */
#ifndef BEGIN_C_DECLS
# ifdef __cplusplus
#  define BEGIN_C_DECLS extern "C" {
#  define END_C_DECLS   }
# else
#  define BEGIN_C_DECLS
#  define END_C_DECLS
# endif
#endif /* BEGIN_C_DECLS */
                                                                                
BEGIN_C_DECLS
                                                                                
 
/*
 * We encapsulated GNU obstack to provide better interface,
 * All of GNU obstack functions and macros are provided in upper-case
 * names. For example, call OBSTACK_INIT() instead obstack_init(),
 * and use OBSTACK_CHUNK_SIZE() rather than obstack_chunk_size().
 *
 * obsutil wrappers -- that is, GNU obstack wrapper functions and macros
 * -- are the same as original GNU obstack functions in terms of argument
 * types and numbers.  It is much better to use obsutil wrappers because
 * it provides some error condition directly via return values.
 *
 * For example, the return type of obstack_init() is `void'. You will not
 * know weather the call was successful before installing obstack error
 * handler.  But OBSTACK_INIT() returns 0 if the call was successful,
 * otherwise it returns -1.
 *
 * All obsutils wrapper which returns 'int' type returns zero on success,
 * otherwise returns -1.  Note that some wrapper will not generate any
 * error. In this case, the return values are the same as the original
 * functions.
 *
 * All obsutils wrapper which returns some pointer type returns NULL on
 * failure.
 */
                                                                                
extern int obstack_errno_;
                                                                                
typedef void (*obstack_alloc_failed_handler_t)(void);
extern void obsutil_alloc_failed_handler(void);
                                                                                
/*
 * You should call obsutil_init() before calling any function or using
 * any macro in this header file.  obsutil_init() modifies the
 * global variable `obstack_alloc_failed_handler' to check errors.
 *
 * If you've used your own handler for `obstack_alloc_failed_handler',
 * you should call obsutil_alloc_failed_handler() in your own handler.
 *
 * If you're not sure, just call obsutil_init().
 */
extern obstack_alloc_failed_handler_t obsutil_init(void);
                                                                                
#define OBS_ERROR_CLEAR         do { obstack_errno_ = 0; } while (0)
#define OBS_ERROR_SET           do { obstack_errno_ = 1; } while (0)
#define OBS_ERROR               (obstack_errno_ != 0)
                                                                                
                                                                                
static __inline__ int
OBSTACK_INIT(struct obstack *stack)
{
  obstack_init(stack);
  if (OBS_ERROR)
    return -1;
  return 0;
}
                                                                                
                                                                                
static __inline__ int
OBSTACK_BEGIN(struct obstack *stack, int size)
{
  OBS_ERROR_CLEAR;
  obstack_begin(stack, size);
  if (OBS_ERROR)
    return -1;
  return 0;
}
                                                                                
                                                                                
static __inline__ void *
OBSTACK_ALLOC(struct obstack *stack, int size)
{
  void *ptr;
  OBS_ERROR_CLEAR;
  ptr = obstack_alloc(stack, size);
  if (OBS_ERROR)
    return 0;
  return ptr;
}
                                                                                
                                                                                
static __inline__ void *
OBSTACK_COPY(struct obstack *stack, void *address, int size)
{
  void *ptr;
  OBS_ERROR_CLEAR;
  ptr = obstack_copy(stack, address, size);
  if (obstack_errno_)
    return 0;
  return ptr;
}
                                                                                
                                                                                
static __inline__ void *
OBSTACK_COPY0(struct obstack *stack, void *address, int size)
{
  void *ptr;
  OBS_ERROR_CLEAR;
  ptr = obstack_copy0(stack, address, size);
  if (obstack_errno_)
    return 0;
  return ptr;
}
                                                                                
                                                                                
static __inline__ void
OBSTACK_FREE(struct obstack *stack, void *object)
{
  obstack_free(stack, object);
}
                                                                                
                                                                                
static __inline__ int
OBSTACK_BLANK(struct obstack *stack, int size)
{
  OBS_ERROR_CLEAR;
  obstack_blank(stack, size);
  if (obstack_errno_)
    return -1;
  return 0;
}
                                                                                
                                                                                
static __inline__ int
OBSTACK_GROW(struct obstack *stack, void *data, int size)
{
  OBS_ERROR_CLEAR;
  obstack_grow(stack, data, size);
  if (obstack_errno_)
    return -1;
  return 0;
}
                                                                                
                                                                                
static __inline__ int
OBSTACK_GROW0(struct obstack *stack, void *data, int size)
{
  OBS_ERROR_CLEAR;
  obstack_grow0(stack, data, size);
  if (obstack_errno_)
    return -1;
  return 0;
}
                                                                                
                                                                                
static __inline__ int
OBSTACK_1GROW(struct obstack *stack, char c)
{
  OBS_ERROR_CLEAR;
  obstack_1grow(stack, c);
  if (obstack_errno_)
    return -1;
  return 0;
}
                                                                                
                                                                                
static __inline__ int
OBSTACK_PTR_GROW(struct obstack *stack, void *data)
{
  OBS_ERROR_CLEAR;
  obstack_ptr_grow(stack, data);
  if (obstack_errno_)
    return -1;
  return 0;
}
                                                                                
                                                                                
static __inline__ int
OBSTACK_INT_GROW(struct obstack *stack, int data)
{
  OBS_ERROR_CLEAR;
  obstack_int_grow(stack, data);
  if (obstack_errno_)
    return -1;
  return 0;
}
                                                                                
                                                                                
static __inline__ void *
OBSTACK_FINISH(struct obstack *stack)
{
  return obstack_finish(stack);
}
                                                                                
                                                                                
static __inline__ int
OBSTACK_OBJECT_SIZE(struct obstack *stack)
{
  return obstack_object_size(stack);
}
                                                                                
                                                                                
static __inline__ int
OBSTACK_ROOM(struct obstack *stack)
{
  return obstack_room(stack);
}
                                                                                
                                                                                
static __inline__ void
OBSTACK_1GROW_FAST(struct obstack *stack, char c)
{
  obstack_1grow_fast(stack, c);
}
                                                                                
                                                                                
static __inline__ void
OBSTACK_INT_GROW_FAST(struct obstack *stack, int data)
{
  obstack_int_grow_fast(stack, data);
}
                                                                                
                                                                                
static __inline__ void
OBSTACK_BLANK_FAST(struct obstack *stack, int size)
{
  obstack_blank_fast(stack, size);
}
                                                                                
                                                                                
static __inline__ void *
OBSTACK_BASE(struct obstack *stack)
{
  return obstack_base(stack);
}
                                                                                
                                                                                
static __inline__ void *
OBSTACK_NEXT_FREE(struct obstack *stack)
{
  return obstack_next_free(stack);
}
                                                                                
                                                                                
static __inline__ int
OBSTACK_ALIGNMENT_MASK(struct obstack *stack)
{
  return obstack_alignment_mask(stack);
}
                                                                                
                                                                                
static __inline__ int
OBSTACK_CHUNK_SIZE(struct obstack *stack)
{
  return obstack_chunk_size(stack);
}
                                                                                
                                                                                
struct os_slist_ {
  void *data;
  struct os_slist_ *next;
};
typedef struct os_slist_ os_slist_t;
                                                                                
#define OS_SLIST_DATA(list)     ((list)->data)
#define OS_SLIST_NEXT(list)     ((list)->next)
                                                                                
struct os_slist_man_ {
  os_slist_t *grave;
  struct obstack *stack;        /* backward reference */
                                                                                
  int num_zombies;
  int num_nodes;
};
typedef struct os_slist_man_ os_slist_man_t;
                                                                                
                                                                                
extern os_slist_man_t *os_slist_init(struct obstack *stack);
extern os_slist_t *os_slist_node_new(os_slist_man_t *manager, void *data);
extern os_slist_t *os_slist_new_v(os_slist_man_t *manager, int nelem, ...);
                                                                                
                                                                                
static __inline__ void *
os_slist_node_delete_(os_slist_man_t *manager, os_slist_t *node)
{
  void *ret = node->data;
                                                                                
  node->next = manager->grave;
  manager->grave = node;
  manager->num_zombies++;
  return ret;
}
                                                                                
                                                                                
static __inline__ void
os_slist_delete(os_slist_man_t *manager, os_slist_t *list)
{
  os_slist_t *ptr = list;
                                                                                
  while (ptr) {
    os_slist_t *tmp = ptr->next;
    os_slist_node_delete_(manager, ptr);
    ptr = tmp;
  }
}
                                                                                
                                                                                
static __inline__ os_slist_t *
os_slist_append(os_slist_man_t *manager, os_slist_t *dest, os_slist_t *src)
{
  os_slist_t *last, *tmp;
                                                                                
  for (tmp = dest; tmp != NULL; tmp = tmp->next)
    last = tmp;
                                                                                
  last->next = src;
  return dest;
}
                                                                                
                                                                                
static __inline__ os_slist_t *
os_slist_prepend(os_slist_man_t *manager, os_slist_t *dest, os_slist_t *src)
{
  os_slist_t *last, *tmp;
                                                                                
  for (tmp = src; tmp != NULL; tmp = tmp->next)
    last = tmp;
                                                                                
  last->next = dest;
  return src;
}
                                                                                
                                                                                
static __inline__ os_slist_t *
os_slist_next(os_slist_man_t *manager, os_slist_t *list)
{
  return list->next;
}
                                                                                
                                                                                
static __inline__ os_slist_t *
os_slist_find_first(os_slist_man_t *manager,
                    os_slist_t *list, void *data)
{
  os_slist_t *ptr;
  for (ptr = list; ptr != NULL; ptr = ptr->next)
    if (ptr->data == data)
      return ptr;
  return 0;
}
                                                                                
                                                                                
static __inline__ os_slist_t *
os_slist_find_nth(os_slist_man_t *manager,
                  os_slist_t *list, void *data, int nth)
{
  os_slist_t *ptr;
  int match = 0;
                                                                                
  for (ptr = list; ptr != 0; ptr = ptr->next) {
    if (ptr->data == data) {
      if (match == nth)
        return ptr;
      match++;
    }
  }
  return 0;
}
                                                                                
                                                                                
static __inline__ os_slist_t *
os_slist_find_last(os_slist_man_t *manager,
                   os_slist_t *list, void *data)
{
  os_slist_t *ptr, *ptr2 = 0;
                                                                                
  for (ptr = list; ptr != NULL; ptr = ptr->next) {
    if (ptr->data == data) {
      ptr2 = ptr;
    }
  }
  return ptr2;
}
                                                                                
                                                                                
END_C_DECLS
                                                                                
#endif  /* OBSUTIL_H_ */

obsutil.c

/* $Id: obsutil,v 1.2 2004/12/05 01:15:02 kss Exp kss $ */
/*
 * GNU obstack wrapper with some utilities
 * Copyright (C) 2003, 2004  Seong-Kook Shin <cinsky@gmail.com>
 */
#include <assert.h>
#include <stdarg.h>
 
#include <obsutil.h>
 
 
int obstack_errno_ = 0;
 
 
void
obsutil_alloc_failed_handler(void)
{
  obstack_errno_ = 1;
}
 
 
obstack_alloc_failed_handler_t
obsutil_init(void)
{
  obstack_alloc_failed_handler_t handler = obstack_alloc_failed_handler;
  obstack_alloc_failed_handler = obsutil_alloc_failed_handler;
  return handler;
}
 
 
os_slist_man_t *
os_slist_init(struct obstack *stack)
{
  os_slist_man_t *manager;
  assert(OBSTACK_OBJECT_SIZE(stack) == 0);
 
  manager = OBSTACK_ALLOC(stack, sizeof(*manager));
  if (obstack_errno_)
    return 0;
  manager->grave = 0;
  manager->stack = stack;
 
  manager->num_zombies = 0;
  manager->num_nodes = 0;
 
  return manager;
}
 
                                                                                
os_slist_t *
os_slist_node_new(os_slist_man_t *manager, void *data)
{
  os_slist_t *node;
  assert(OBSTACK_OBJECT_SIZE(manager->stack) == 0);
                                                                                
  if (manager->grave) {
    node = manager->grave;
    manager->grave = node->next;
    manager->num_zombies--;
  }
  else {
    node = OBSTACK_ALLOC(manager->stack, sizeof(*node));
    if (obstack_errno_)
      return 0;
    manager->num_nodes++;
  }
  node->next = 0;
  node->data = data;
                                                                                
  return node;
}
                                                                                
                                                                                
os_slist_t *
os_slist_new_v(os_slist_man_t *manager, int nelem, ...)
{
  va_list argptr;
  int i;
  os_slist_t *list = 0, *last, *ptr;
                                                                                
  if (nelem < 1)
    return 0;
                                                                                
  va_start(argptr, nelem);
  list = os_slist_node_new(manager, va_arg(argptr, void *));
  last = list;
                                                                                
  for (i = 1; i < nelem; i++) {
    ptr = os_slist_node_new(manager, va_arg(argptr, void *));
    if (!ptr) {
      os_slist_delete(manager, list);
      va_end(argptr);
      return 0;
    }
    last->next = ptr;
    last = ptr;
  }
                                                                                
  va_end(argptr);
  return list;
}
                                                                                
                                                                                
#ifdef TEST_OBSUTIL
                                                                                
#include <error.h>
                                                                                
int
main(void)
{
  struct obstack stack_;
  struct obstack *stack = &stack_;
  os_slist_man_t *manager;
  os_slist_t *list;
                                                                                
  obsutil_init();
                                                                                
  if (OBSTACK_INIT(stack) < 0)
    error(1, 0, "obstack_init() failed");
                                                                                
  manager = os_slist_init(stack);
  if (!manager)
    error(1, 0, "os_slist_init() failed");
                                                                                
  list = os_slist_new_v(manager, 4, NULL, NULL, NULL, NULL);
                                                                                
                                                                                
  return 0;
}
#endif  /* TEST_OBSUTIL */


ID
Password
Join
Might as well be frank, monsieur. It would take a miracle to get you out of Casablanca.


sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2004-12-05 10:15:02
Processing time 0.0083 sec