示例#1
0
文件: main.c 项目: itmm/waelzer
/*>
## Processing the input files

So now we can start to process the files. Let's jump to the `main` function and see the good parts. First we get files to process and open the output file.

If there are no input files, we terminate and wont overwrite an existing `README.md` file (just be save).
<*/
int main(int argc, char **argv) {
	str_lst *files = get_list_of_files();
	return_unless(files, EXIT_FAILURE, "can't read list of files");
	return_unless(str_lst_count(files), EXIT_SUCCESS, "nothing to process");

	FILE *out = fopen("README.md", "w");
	if (!out) {
		str_lst_free(files);
		return_unless(false, EXIT_FAILURE, "can't open README.md");
	}
/*>
Now we open each file and call the process function. The function needs to know, if the file contains MarkDown directly, or is a source code file, that only contains MarkDown in special comment blocks.

We do the suffix magic to check, if it ends in `.md`. Otherwise we will assume it a source code file.
<*/
	for (char **cur = str_lst_begin(files); cur != str_lst_end(files); ++cur) {
		FILE *in = fopen(*cur, "r");
		if (!in) {
			fclose(out);
			return_unless(false, EXIT_FAILURE, "can't read \"%s\"", *cur);
		}

		printf("processing \"%s\" ... ", *cur);
		size_t length = strlen(*cur);
		bool code_file = length < 3 || strcmp(*cur + length - 3, ".md");
		puts(process_file(in, out, code_file) ? "ok" : "FAILED");
		fclose(in);
	}
	fclose(out);
	str_lst_free(files);
}
示例#2
0
文件: str_lst.c 项目: itmm/waelzer
/*>
The pointer adjustment checks both memory blocks and adjusts the other pointers of the `str_lst` structure.
<*/
static bool str_lst_adjust_pointers(str_lst *sl, int capacity) {
	return_unless(sl, false, "no list");
	return_unless(sl->begin, false, "no memory for buffer");
	sl->end = sl->begin;
	sl->capacity = sl->begin + capacity;
	return true;
}
示例#3
0
void
renderer::map (data::map const &map)
{
  static int const layer = -1;

  for (size_t y = 0; y < array_size (win); y++)
    for (size_t x = 0; x < array_size (win[y]); x++)
      win[y][x] = L'_';

  static data::glyph const space  = { { {  0,  0, L'?' }, {  0,  0, L'?' } } };
  static data::glyph const player = { { {  0,  0, L'@' }, {  0,  0, L'@' } } };

  int const playerx = (W - !(W % 2)) / 2;
  int const playery = (H - !(H % 2)) / 2;

  int const offx = (map.w - W) / 2;
  int const offy = (map.h - H) / 2;

  return_unless (!data::glyphs.empty ());
 
  for (int y = 0; y < H; y++)
    {
      int const mapy = y + map.y + offy;
      if (!map.rows.has (mapy))
        continue;
      auto const &row = map.rows[mapy];
      for (int x = 0; x < W; x++)
        {
          int const mapx = x + map.x + offx;
          if (!row.has (mapx))
            continue;
          data::map::cell const &cell = row[mapx];
          u32 const face = select_face (cell.face, layer);

          data::glyph const *glyph;

          int const winy = y * 1;
          int const winx = x * 2;

          if (x == playerx && y == playery)
            glyph = &player;
          else if (face && face < data::glyphs.size ()) // TODO: warn about face >= size
            glyph = &data::glyphs[face];
          else
            glyph = &space;

          return_unless (winy >= 0);
          return_unless (winx >= 0);
          return_unless (winy < int (array_size ( win)));
          return_unless (winx < int (array_size (*win)));

          win[winy][winx + 0] = (*glyph)[0].text;
          win[winy][winx + 1] = (*glyph)[1].text;
        }
    }
}
示例#4
0
文件: str_lst.c 项目: itmm/waelzer
/*>
In the consuming function we do the heavy lifting, if the capacity is exceeded. Then we double the capacity until we grow so big, that we switch to a linear growth.

We reallocate the buffer for the new size, adjust the pointers and add the element. If we can't reallocate the buffer, nothing will be changed.
<*/
bool str_lst_add_and_consume(str_lst *sl, char *str) {
	return_unless(sl, false, "no list");
	if (sl->end == sl->capacity) {
		int old_count = sl->capacity - sl->begin;
		int new_count = old_count + MIN(old_count, 1024);
		void *newBuffer = realloc(sl->begin, new_count * sizeof(char **));
		return_unless(newBuffer, false, "can't expand buffer");
		sl->begin = newBuffer;
		sl->end = sl->begin + old_count;
		sl->capacity = sl->begin + new_count;
	}
	*sl->end++ = str;
	return true;
}
示例#5
0
void
inventory_manager::upditem (u08 flags, u32 location, data::item const &item)
{
  data::item *current = get (item.tag);

  return_unless (current != NULL);

  if (flags & UPD_LOCATION)
    {
      data::item save = *current;
      delitem ({ item.tag });
      current = &merge (inventories[location], save);
    }

  if (flags & UPD_ANIM)      current->anim      = item.anim;
  if (flags & UPD_ANIMSPEED) current->animspeed = item.animspeed;
  if (flags & UPD_FACE)      current->face      = item.face;
  if (flags & UPD_FLAGS)     current->flags     = item.flags;
  if (flags & UPD_NROF)      current->nrof      = item.nrof;
  if (flags & UPD_WEIGHT)    current->weight    = item.weight;

  if (flags & UPD_NAME)
    {
      current->singular = item.singular;
      current->plural   = item.plural;
    }

  update ();
}
示例#6
0
static void
render_rusage (ndk::window &widget, int row = 8)
{
  static timeval start;

  ndk::pen pen (widget);
  return_unless (pen.move (2, row));

  if (!start.tv_sec)
    gettimeofday (&start, NULL);

  timeval now, diff;
  gettimeofday (&now, NULL);
  timersub (&now, &start, &diff);

  struct rusage usage;
  getrusage (RUSAGE_SELF, &usage);

  pen.write ( "[CPU: %ld.%02lds"
            , usage.ru_utime.tv_sec + usage.ru_stime.tv_sec
            , (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec)
            / 10000
            );
  pen.write ( "   Cells: %d (%dKiB)"
            , data::cell_count
            , data::cell_count * sizeof (data::map::cell) / 1024
            );
  pen.write ( "   RES: %ldKiB"
            , usage.ru_maxrss
            );
  pen.write ( "   RT: %ld:%02ld]"
            , diff.tv_sec / 60
            , diff.tv_sec % 60
            );
}
示例#7
0
文件: str.c 项目: itmm/waelzer
char *str_cons(int count, ...) {
	return_unless(count >= 0, empty, "count must not be negative");
	if (!count) { return empty; }

	va_list args1;
	va_list args2;
	va_start(args1, count);
	va_copy(args2, args1);
/*>
The calculation of the length is straight forward. We only have to watch out for `NULL` strings, that will be silently ignored.
<*/
	size_t length = 0;
	for (int i = count; i; --i) {
		const char *current = va_arg(args1, const char *);
		if (current) length += strlen(current);
	}
	va_end(args1);
/*>
The result buffer must be one byte bigger to store the terminating null byte.
<*/
	char *result = malloc(length + 1);
/*>
The `copy_args` function may throw an error. We put it in a different function, so we can free the second argument list, even, if an error is raised.
<*/
	copy_args(result, count, args2);
	va_end(args2);

	return result ? : empty;
}
示例#8
0
文件: gc.c 项目: itmm/hash
gc_node *find_node(void *ptr) {
	return_unless(NULL, ptr);
	for (gc_node *cur = all_nodes; cur; cur = cur->next) {
		if (cur->ptr == ptr) return cur;
	}
	return NULL;
}
示例#9
0
文件: rc.c 项目: itmm/hash
void *rc_false() {
    static void *_singleton = NULL;
    if (!_singleton) {
        _singleton = rc_alloc(0, rc_type_false, NULL);
        return_unless(NULL, _singleton);
    }
    return rc_retain(_singleton);
}
示例#10
0
文件: str_lst.c 项目: itmm/waelzer
str_lst *str_lst_create(int min_capacity) {
	int capacity = MAX(min_capacity, 8);
	str_lst *sl = malloc(sizeof(str_lst));
	return_unless(sl, NULL, "no memory for struct");
	sl->begin = malloc(sizeof(char **) * capacity);
	if (!str_lst_adjust_pointers(sl, capacity)) {
		free(sl);
		sl = NULL;
	}

	return sl;
}
示例#11
0
文件: rc.c 项目: itmm/hash
void *rc_alloc(size_t size, rc_type type, dealloc_fn *dealloc) {
    const size_t data_size = padded_rc_size();
    void *result = NULL;
    if (size <= SIZE_MAX - data_size) {
        size += data_size;
        result = malloc(size);
        return_unless(NULL, result);
        struct rc *r = result;
        r->dealloc = dealloc;
        r->count = 1;
        r->type = type;
        result += data_size;
    } else {
        log_error("can't alloc %lu bytes (too big)", size);
    }
    return result;
}
示例#12
0
文件: gc.c 项目: itmm/hash
static bool mark_decendents(void *ptr) {
    return_unless(false, ptr);
    
    bool something_changed = false;
    for (gc_dispatcher *dispatcher = dispatchers; dispatcher; dispatcher = dispatcher->next) {
        if (dispatcher->is_matching(ptr)) {
            int count = dispatcher->number_of_references(ptr);
            for (int i = 0; i < count; ++i) {
                void *ref = dispatcher->reference_number(ptr, i);
                if (ref) {
                    gc_node *ref_node = find_node(ref);
                    if (ref_node && ref_node->marked == UNMARKED) {
                        ref_node->marked = MARKED;
                        something_changed = true;
                    }
                }
            }
            break;
        }
    }
    return something_changed;
}
示例#13
0
void
map_widget::draw ()
{
  frame::draw ();

  if (!map)
    return;

  static int const layer = -1;

  int const W = this->width  () / 2;
  int const H = this->height ();
  ndk::pen pen (*this);

  static data::glyph const space  = { { {  0,  0, L' ' }, {  0,  0, L' ' } } };
#if HIGHLIGHT_PLAYER
  static data::glyph const player = { { {  0,  0, L'@' }, { 13, 13, L'@' } } };
#endif

#if HIGHLIGHT_PLAYER
  int const playerx = (W - !(W % 2)) / 2;
  int const playery = (H - !(H % 2)) / 2;
#endif

  int const offx = (map->w - W) / 2;
  int const offy = (map->h - H) / 2;

  return_unless (!data::glyphs.empty ());
 
  for (int y = 1; y < H - 1; y++)
    {
      int const mapy = y + map->y + offy;
      if (!map->rows.has (mapy))
        continue;
      auto const &row = map->rows[mapy];
      for (int x = 1; x < W - 1; x++)
        {
          int const mapx = x + map->x + offx;
          if (!row.has (mapx))
            continue;
          data::map::cell const &cell = row[mapx];
          u32 const face = select_face (cell.face, layer);

          data::glyph const *glyph;

          int const winy = y * 1;
          int const winx = x * 2;

#if HIGHLIGHT_PLAYER
          if (x == playerx && y == playery)
            glyph = &player;
#else
          if (0)
            ;
#endif
          else if (face && face < data::glyphs.size ()) // TODO: warn about face >= size
            glyph = &data::glyphs[face];
          else
            glyph = &space;

          return_unless (winy >= 0);
          return_unless (winx >= 0);
          return_unless (winy < H);
          return_unless (winx < W * 2);

          return_unless (pen.move (winx, winy));
          write (pen, *glyph, cell.darkness);
        }
    }

#if HIGHLIGHT_PLAYER
  // 19:15 < n0nsense> pippijn: kannst du nethack-mäßig noch den cursor auf den player setzen?
  if (active ())
    {
      pen.move (playerx, playery);
      ndk::app->cursor_on ();
    }
  else
    ndk::app->cursor_off ();
#endif

  if (getenv ("DCLIENT_ONESHOT"))
    {
      delete ndk::app;
      exit (0);
    }

  pen.set_color ({ }); // reset
}
示例#14
0
void
stats_widget::draw ()
{
  frame::draw ();

  if (!stats)
    return;

  ndk::pen pen (*this);

  int const margin = 2;

  return_unless (pen.move (margin - 1, 1)); pen.write (stats->s_range);
  return_unless (pen.move (margin, 2)); pen.write (stats->s_title);
  return_unless (pen.move (margin, 3));
  if (stats->s_exp64)
    pen.write ("Exp: %'ld", stats->s_exp64);
  else if (stats->s_exp)
    pen.write ("Exp: %d", stats->s_exp);
  else
    pen.write ("Exp: 0");

  int row = 4;
  {
    int const shift = 12;
    int col = 0;

    return_unless (pen.move (margin + shift * col++, row)); pen.write ("HP: %d/%d", stats->s_hp, stats->s_maxhp);
    return_unless (pen.move (margin + shift * col++, row)); pen.write ("SP: %d/%d", stats->s_sp, stats->s_maxsp);
    return_unless (pen.move (margin + shift * col++, row)); pen.write ("GP: %d/%d", stats->s_grace, stats->s_maxgrace);
    return_unless (pen.move (margin + shift * col++, row)); pen.write ("Food: %d/%d", stats->s_food, 999);
  }
  row++;
  {
    int const shift = 12;
    int col = 0;

    return_unless (pen.move (margin + shift * col++, row)); pen.write ("WC: %d", stats->s_wc);
    return_unless (pen.move (margin + shift * col++, row)); pen.write ("AC: %d", stats->s_ac);
    return_unless (pen.move (margin + shift * col++, row)); pen.write ("Dam: %d", stats->s_dam);
    return_unless (pen.move (margin + shift * col++, row)); pen.write ("Speed: %d", stats->s_speed);
    return_unless (pen.move (margin + shift * col++, row)); pen.write ("Weapon speed: %d", stats->s_weap_sp);
  }
  row++;
  {
    int const shift = 8;
    int col = 0;

    return_unless (pen.move (margin + shift * col++, row)); pen.write ("Str: %d", stats->s_str);
    return_unless (pen.move (margin + shift * col++, row)); pen.write ("Dex: %d", stats->s_dex);
    return_unless (pen.move (margin + shift * col++, row)); pen.write ("Con: %d", stats->s_con);
    return_unless (pen.move (margin + shift * col++, row)); pen.write ("Int: %d", stats->s_int);
    return_unless (pen.move (margin + shift * col++, row)); pen.write ("Wis: %d", stats->s_wis);
    return_unless (pen.move (margin + shift * col++, row)); pen.write ("Pow: %d", stats->s_pow);
    return_unless (pen.move (margin + shift * col++, row)); pen.write ("Cha: %d", stats->s_cha);
  }

  render_rusage (*this);
}
示例#15
0
/*>
The execution of the buffer is trivial, but can still fail.
<*/
static bool execute_buffer(char *buffer) {
	return_unless(buffer, false, "no buffer");
	return_unless(!system(buffer), false, "can't execute '%s'", buffer);
	return true;
}
示例#16
0
文件: rc.c 项目: itmm/hash
rc_type rc_get_type(void *rc) {
    return_unless(rc_type_unknown, rc);
    struct rc *r = rc - padded_rc_size();
    return r->type;
}