예제 #1
0
파일: fortune.c 프로젝트: hyperrealm/cbase
c_fortune_db_t *C_fortune_opendb(const char *basename)
{
  c_fortune_db_t *db;
  struct stat stbuf;
  char *buf;
  size_t len;

  len = strlen(basename) + strlen(C_FORTUNE_INDEX_EXT) + 2;

  buf = C_newstr(len);
  snprintf(buf, len, "%s.%s", basename, C_FORTUNE_INDEX_EXT);

  if(access(basename, (F_OK | R_OK)) || access(buf, (F_OK | R_OK)))
  {
    C_free(buf);
    return(NULL);
  }

  db = C_new(c_fortune_db_t);

  db->data = fopen(basename, "r");
  db->index = fopen(buf, "r");

  stat(basename, &stbuf);
  db->filelen = stbuf.st_size;

  stat(buf, &stbuf);
  db->count = (stbuf.st_size / sizeof(long));

  C_free(buf);

  return(db);
}
예제 #2
0
/******************************************************************************\
 Decreases the reference count. If there are no references left, the cleanup
 function is called on the data and the memory is freed.
\******************************************************************************/
void C_ref_down_full(const char *file, int line, const char *function,
                     c_ref_t *ref)
{
        if (!ref)
                return;
        if (ref->refs < 1)
                C_error_full(file, line, function,
                             "Invalid reference structure");
        ref->refs--;
        if (ref->refs > 0) {
                if (c_mem_check.value.n)
                        C_trace_full(file, line, function,
                                     "Dereferenced '%s' (%d refs)",
                                     ref->name, ref->refs);
                return;
        }
        if (ref->root) {
                if (*ref->root == ref)
                        *ref->root = ref->next;
                if (ref->prev)
                        ref->prev->next = ref->next;
                if (ref->next)
                        ref->next->prev = ref->prev;
        }
        if (c_mem_check.value.n)
                C_trace_full(file, line, function, "Freed '%s'",
                             ref->name, ref->refs);
        if (ref->cleanup_func)
                ref->cleanup_func(ref);
        C_free(ref);
}
예제 #3
0
/******************************************************************************\
 Reloads the testing sprite when [r_test_sprite] or [r_test_sprites] changes.
\******************************************************************************/
static int test_sprite_update(c_var_t *var, c_var_value_t value)
{
        r_texture_t *texture;
        int i;

        /* Cleanup old sprites */
        if (test_sprites) {
                for (i = 0; i < r_test_sprite_num.value.n; i++)
                        R_billboard_cleanup(test_sprites + i);
                C_free(test_sprites);
                test_sprites = NULL;
        }

        /* Create new sprites */
        var->value = value;
        if (r_test_sprite_num.value.n < 1 || !r_test_sprite.value.s[0])
                return TRUE;
        C_rand_seed((unsigned int)time(NULL));
        test_sprites = C_malloc(r_test_sprite_num.value.n *
                                sizeof (*test_sprites));
        texture = R_texture_load(r_test_sprite.value.s, TRUE);
        for (i = 0; i < r_test_sprite_num.value.n; i++) {
                c_vec3_t origin;

                R_billboard_init(test_sprites + i, texture);
                origin = C_vec3(r_globe_radius * (C_rand_real() - 0.5f),
                                r_globe_radius * (C_rand_real() - 0.5f),
                                r_globe_radius + 3.f);
                test_sprites[i].world_origin = origin;
                test_sprites[i].sprite.angle = C_rand_real();
        }
        R_texture_free(texture);

        return TRUE;
}
예제 #4
0
파일: pty.c 프로젝트: hyperrealm/cbase
c_bool_t C_pty_destroy(c_pty_t *pty)
{
  if(! pty)
    return(FALSE);

  close(pty->master_fd);
  close(pty->slave_fd);
  C_free(pty);

  return(TRUE);
}
예제 #5
0
/******************************************************************************\
 Cleanup test assets.
\******************************************************************************/
void R_free_test_assets(void)
{
        R_model_cleanup(&test_model);
        if (test_sprites) {
                int i;

                for (i = 0; i < r_test_sprite_num.value.n; i++)
                        R_billboard_cleanup(test_sprites + i);
                C_free(test_sprites);
        }
        R_text_cleanup(&test_text);
}
예제 #6
0
파일: fortune.c 프로젝트: hyperrealm/cbase
c_bool_t C_fortune_closedb(c_fortune_db_t *db)
{
  if(!db)
    return(FALSE);

  fclose(db->data);
  fclose(db->index);

  C_free(db);

  return(TRUE);
}
예제 #7
0
파일: fortune.c 프로젝트: hyperrealm/cbase
c_bool_t C_fortune_indexdb(const char *basename)
{
  char *buf, databuf[128];
  FILE *fp, *ip;
  long offset = 0;
  size_t bufsz;

  if(!(fp = fopen(basename, "r")))
    return(FALSE);

  bufsz = strlen(basename) + strlen(C_FORTUNE_INDEX_EXT) + 2;
  buf = C_newstr(bufsz);
  snprintf(buf, bufsz, "%s.%s", basename, C_FORTUNE_INDEX_EXT);

  if(!(ip = fopen(buf, "w+")))
  {
    fclose(fp);
    C_free(buf);
    return(FALSE);
  }

  fwrite(&offset, sizeof(offset), 1, ip);

  while(C_io_gets(fp, databuf, sizeof(databuf), '\n') != EOF)
  {
    if(!strcmp(databuf, C_FORTUNE_SEPARATOR))
    {
      offset = htonl(ftell(fp));
      fwrite(&offset, sizeof(offset), 1, ip);
    }
  }

  C_free(buf);

  fclose(fp);
  fclose(ip);
  return(TRUE);
}
예제 #8
0
/******************************************************************************\
 Run some test to see if memory checking actually works. Note that code here
 is intentionally poor, so do not fix "bugs" here they are there for a reason.
\******************************************************************************/
void C_test_mem_check(void)
{
        char *ptr;
        int i;

        switch (c_mem_check.value.n) {
        case 0:
        case 1: return;
        case 2: C_debug("Normal operation, shouldn't fail");
                ptr = C_malloc(1024);
                C_free(ptr);
                ptr = C_calloc(1024);
                C_realloc(ptr, 2048);
                C_realloc(ptr, 512);
                C_free(ptr);
                return;
        case 3: C_debug("Intentionally leaking memory");
                ptr = C_malloc(1024);
                return;
        case 4: C_debug("Freeing unallocated memory");
                C_free((void *)0x12345678);
                break;
        case 5: C_debug("Double freeing memory");
                ptr = C_malloc(1024);
                C_free(ptr);
                C_free(ptr);
                break;
        case 6: C_debug("Simulating memory underrun");
                ptr = C_malloc(1024);
                for (i = 0; i > -NO_MANS_LAND_SIZE / 2; i--)
                        ptr[i] = 42;
                C_free(ptr);
                break;
        case 7: C_debug("Simulating memory overrun");
                ptr = C_malloc(1024);
                for (i = 1024; i < 1024 + NO_MANS_LAND_SIZE / 2; i++)
                        ptr[i] = 42;
                C_free(ptr);
                break;
        case 8: C_debug("Reallocating unallocated memory");
                ptr = C_realloc((void *)0x12345678, 1024);
                break;
        case 9: C_debug("Intentionally leaking string");
                ptr = C_malloc(1024);
                C_strncpy(ptr, "This string was leaked", 1024);
                return;
        default:
                C_error("Unknown memory check test %d",
                        c_mem_check.value.n);
        }
        C_error("Memory check test %d failed", c_mem_check.value.n);
}
예제 #9
0
파일: fortune.c 프로젝트: hyperrealm/cbase
const char *C_fortune_select(c_fortune_db_t *db)
{
  char *buf;
  int idx;
  unsigned long offset, end, fsize;

  if(!db)
    return(NULL);

  idx = C_random(db->count);

  fseek(db->index, (idx * sizeof(unsigned long)), SEEK_SET);
  if(fread(&offset, sizeof(unsigned long), 1, db->index) != 1)
    return(NULL);

  offset = ntohl(offset);

  if(idx == (db->count - 1))
    fsize = db->filelen - offset;
  else
  {
    if(fread(&end, sizeof(unsigned long), 1, db->index) != 1)
      return(NULL);

    fsize = ntohl(end) - offset - 2;
  }

  fseek(db->data, offset, SEEK_SET);

  buf = C_newb(fsize + 1);
  if(fread(buf, fsize, 1, db->data) != 1)
  {
    C_free(buf);
    return(NULL);
  }

  return(buf);
}
예제 #10
0
/******************************************************************************\
 Clean up after the array.
\******************************************************************************/
void C_array_cleanup(c_array_t *array)
{
        C_free(array->data);
        memset(array, 0, sizeof (*array));
}
예제 #11
0
파일: random.c 프로젝트: hyperrealm/cbase
static void __C_random_destructor(void *arg)
{
  C_free(arg);
}
예제 #12
0
/******************************************************************************\
 Dispatches basic widget events and does some checks to see if the event
 applies to this widget. Cleans up resources on I_EV_CLEANUP and propagates
 the event to all child widgets.

 Key focus follows the mouse. Only one widget can have keyboard focus at any
 time and that is the last widget that the mouse cursor passed over that
 could take keyboard input.

 Events filter down through containers to child widgets. The ordering will call
 all of a widget's parent containers before calling the widget and will call
 all of the children of a widget before calling a sibling.

 Always call this function instead of a widget's class event function in order
 to ensure correct event filtering and propagation.
\******************************************************************************/
void I_widget_event(i_widget_t *widget, i_event_t event)
{
        if (!widget)
                return;
        if (!widget->name[0] || !widget->event_func) {
                if (event == I_EV_CLEANUP)
                        return;
                C_error("Propagated %s to uninitialized widget, parent is %s",
                        I_event_to_string(event),
                        widget->parent ? widget->parent->name : "NULL");
        }

        /* The only event an unconfigured widget can handle is I_EV_CONFIGURE */
        if (!widget->configured && event != I_EV_CONFIGURE) {
                if (widget->auto_configure)
                        I_widget_event(widget, I_EV_CONFIGURE);
                if (!widget->configured)
                        C_error("Propagated %s to unconfigured %s",
                                I_event_to_string(event), widget->name);
        }

        /* Print out the event in debug mode */
        if (i_debug.value.n >= 2)
                switch (event) {
                default:
                        C_trace("%s --> %s", I_event_to_string(event),
                                widget->name);
                case I_EV_RENDER:
                case I_EV_MOUSE_MOVE:
                case I_EV_MOUSE_FOCUS:
                case I_EV_GRAB_FOCUS:
                case I_EV_KEY_UP:
                case I_EV_MOUSE_UP:
                        break;
                }

        /* Before handling and propagating event to children */
        switch (event) {
        case I_EV_CLEANUP:
                if (c_mem_check.value.n)
                        C_trace("Freeing %s", widget->name);
                break;
        case I_EV_CONFIGURE:
                if (c_mem_check.value.n)
                        C_trace("Configuring %s", widget->name);
                break;
        case I_EV_GRAB_FOCUS:
                if (widget->entry && widget->shown &&
                    widget->state != I_WS_DISABLED)
                        key_focus = widget;
                break;
        case I_EV_HIDE:
                if (!widget->shown)
                        return;
                widget->shown = FALSE;
                widget->event_func(widget, event);
                focus_parent(widget);
                return;
        case I_EV_KEY_DOWN:
                if (widget->steal_keys &&
                    widget->state != I_WS_DISABLED && widget->shown &&
                    widget->state != I_WS_NO_FOCUS)
                        widget->event_func(widget, event);
                return;
        case I_EV_MOUSE_IN:
                if (widget->state == I_WS_READY)
                        widget->state = I_WS_HOVER;
                widget->event_func(widget, event);
                return;
        case I_EV_MOUSE_OUT:
                if (widget->state == I_WS_HOVER || widget->state == I_WS_ACTIVE)
                        widget->state = I_WS_READY;
                widget->event_func(widget, event);
                return;
        case I_EV_MOUSE_DOWN:
                widget->event_func(widget, event);
                return;
        case I_EV_MOUSE_FOCUS:
                if (!check_mouse_focus(widget))
                        return;
                break;
        case I_EV_MOUSE_MOVE:
                if (widget->state == I_WS_READY)
                        I_widget_event(widget, I_EV_MOUSE_IN);
                widget->event_func(widget, event);
                return;
        case I_EV_KEY_FOCUS:
                key_focus = mouse_focus;
                widget->event_func(widget, event);
                return;
        case I_EV_MOVED:
                C_error("I_EV_MOVED should only be generated by "
                        "I_widget_move()");
        case I_EV_RENDER:
                if (!i_debug.value.n && widget->parent &&
                    !C_rect_intersect(widget->origin, widget->size,
                                      widget->parent->origin,
                                      widget->parent->size))
                        return;
                if (i_fade.value.f > 0.f) {
                        float target, rate;

                        target = 0.f;

                        /* Widgets inherit the parent widget's fade */
                        if (widget->shown) {
                                target = 1.f;
                                if (widget->parent)
                                        target = widget->parent->fade;
                        }

                        rate = i_fade.value.f * c_frame_sec;
                        if (widget->state == I_WS_DISABLED) {
                                target *= 0.25f;
                                if (widget->fade <= 0.25f)
                                        rate *= 0.25f;
                        }
                        if (widget->fade < target) {
                                widget->fade += rate;
                                if (widget->fade > target)
                                        widget->fade = target;
                        } else if (widget->fade > target) {
                                widget->fade -= rate;
                                if (widget->fade < target)
                                        widget->fade = target;
                        }

                        /* Widget should never be less faded than its parent */
                        if (widget->parent &&
                            widget->parent->fade < widget->fade)
                                widget->fade = widget->parent->fade;

                        if (widget->fade <= 0.f)
                                return;
                } else if (!widget->shown)
                        return;
                break;
        case I_EV_SHOW:
                if (widget->shown)
                        return;
                widget->shown = TRUE;
                widget->event_func(widget, event);
                find_focus();
                return;
        default:
                break;
        }

        /* Call widget-specific event handler and propagate event down */
        if (widget->event_func(widget, event))
                I_widget_propagate(widget, event);

        /* After handling and propagation to children */
        switch (event) {
        case I_EV_CONFIGURE:
                widget->configured = TRUE;
                break;
        case I_EV_CLEANUP:
                focus_parent(widget);
                if (i_mouse_focus == widget)
                        i_mouse_focus = NULL;
                if (i_key_focus == widget)
                        i_key_focus = NULL;
                if (widget->heap)
                        C_free(widget);
                else
                        C_zero(widget);
                break;
        case I_EV_MOUSE_DOWN:
        case I_EV_MOUSE_UP:
                if (mouse_focus == widget && widget->state == I_WS_READY)
                        widget->state = I_WS_HOVER;
                break;
        default:
                break;
        }
}