Пример #1
0
void tds_elem_set_string(tds_elem *elem, const char *str, size_t size)
{
  elem->type = 's';
  elem->value.str.data = tds_malloc(size);
  if(elem->value.str.data) {
    memcpy(elem->value.str.data, str, size);
    elem->value.str.size = size;
  }
}
Пример #2
0
tds_vec* tds_vec_new(void)
{
  tds_vec *vec = tds_malloc(sizeof(tds_vec));
  if(!vec)
    return NULL;
  vec->data = NULL;
  vec->allocn = 0;
  vec->n = 0;
  vec->refcount = 1;
  return vec;
}
Пример #3
0
void* tds_realloc_rel(void* ptr, int size) {
	if (!ptr) {
		return tds_malloc(size);
	}

	tds_mem_bytes += size;
	void* output = realloc(ptr, size);

	if (!output) {
		tds_logf(TDS_LOG_CRITICAL, "Memory reallocation failure for block of size %d.\n", size);
		return NULL;
	}

	return output;
}
Пример #4
0
void tds_profile_push(struct tds_profile* ptr, const char* name) {
	struct tds_profile_cycle* new_cycle = tds_malloc(sizeof *new_cycle);

	/*
	 * Not really a stack -- more like an N-child expanding tree.
	 * The decision to add as a parallel or child node depends on the current location in the stack.
	 */

	new_cycle->name = name;
	new_cycle->mark_count = 0;
	new_cycle->call_count = 1;
	new_cycle->time_start = tds_clock_get_point();
	new_cycle->time = 0.0f;
	new_cycle->next = ptr->stack;

	ptr->stack = new_cycle;
}
Пример #5
0
struct tds_profile* tds_profile_create(void) {
	struct tds_profile* output = tds_malloc(sizeof *output);

	output->stack = output->list = NULL;
	return output;
}
Пример #6
0
tds_elem *tds_elem_new(void)
{
  return tds_malloc(sizeof(tds_elem));
}
Пример #7
0
struct tds_stringdb* tds_stringdb_create(const char* filename) {
	struct tds_stringdb* output = tds_malloc(sizeof *output);

	output->entry_count = 0;
	output->entries = NULL;

	output->error_entry.data = "ERROR (entry)";
	output->error_entry.len = strlen(output->error_entry.data);

	output->error_offset.data = "ERROR (offset)";
	output->error_offset.len = strlen(output->error_offset.data);

	output->error_empty.data = "ERROR (no strings)";
	output->error_empty.len = strlen(output->error_empty.data);

	char* filename_full = tds_malloc(strlen(filename) + strlen(TDS_STRINGDB_PREFIX) + 1);

	memcpy(filename_full, TDS_STRINGDB_PREFIX, strlen(TDS_STRINGDB_PREFIX));
	memcpy(filename_full + strlen(TDS_STRINGDB_PREFIX), filename, strlen(filename));

	filename_full[strlen(TDS_STRINGDB_PREFIX) + strlen(filename)] = 0;

	tds_logf(TDS_LOG_MESSAGE, "Loading string database from [%s]\n", filename_full);

	FILE* fd = fopen(filename_full, "r");

	if (!fd) {
		tds_logf(TDS_LOG_CRITICAL, "Failed to open string database [%s] for reading.\n", filename_full);
		return NULL;
	}

	tds_free(filename_full);

	char readbuf[TDS_STRINGDB_BUFLEN] = {0}, *readpos = readbuf;

	struct tds_string_db_entry* cur_entry = NULL;
	struct tds_string_db_offset_entry* cur_offset = NULL;

	while (memset(readbuf, 0, sizeof readbuf / sizeof *readbuf) && fgets(readbuf, sizeof readbuf / sizeof *readbuf, fd)) {
		readbuf[strcspn(readbuf, "\n")] = 0;

		switch(*readbuf) {
		case '@':
			/* New string db entry. We allocate a structure on the entries list and start reading indices. */
			readpos = readbuf + 1;

			cur_entry = tds_malloc(sizeof *cur_entry);

			cur_entry->id = tds_malloc(strlen(readpos));
			cur_entry->id_len = strlen(readpos);
			memcpy(cur_entry->id, readpos, cur_entry->id_len);

			cur_entry->next = output->entries;
			output->entries = cur_entry;
			output->entry_count++;

			cur_entry->offset_count = 0;
			cur_entry->offsets = NULL;
			cur_offset = NULL;
			break;
		case '#':
			readpos = readbuf + 1;

			if (!cur_entry) {
				tds_logf(TDS_LOG_WARNING, "Offset was specified but there was no associated string entry. Ignoring.\n");
				break;
			}

			cur_offset = tds_malloc(sizeof *cur_offset);
			cur_offset->offset_id = strtol(readpos, NULL, 0);

			cur_offset->string_count = 0;
			cur_offset->strings = NULL;

			cur_offset->next = cur_entry->offsets;
			cur_entry->offsets = cur_offset;
			cur_entry->offset_count++;
			break;
		case ':':
			readpos = readbuf + 1;

			if (!cur_offset) {
				tds_logf(TDS_LOG_WARNING, "String value given but there was no associated offset entry. Ignoring.\n");
				break;
			}

			struct tds_string_db_offset_entry_string* new_string_entry = tds_malloc(sizeof *new_string_entry);

			{
				int readpos_len = strlen(readpos);
				new_string_entry->str.data = tds_malloc(readpos_len + 1); /* We will allocate more memory than necessary if there are any format strings, but this saves us reallocation overhead. */
				new_string_entry->str.len = 0;

				for (int i = 0; i < readpos_len; ++i) {
					if (readpos[i] == TDS_STRING_FORMAT_SPEC) {
						if (++i >= readpos_len) {
							break;
						}

						tds_logf(TDS_LOG_DEBUG, "started format i %d -> readpos (type) %c\n", i, readpos[i]);

						struct tds_string_format* new_format = tds_malloc(sizeof *new_format);
						new_format->type = readpos[i];
						new_format->pos = new_string_entry->str.len;

						int fields = -1;
						for (int j = 0; j < sizeof tds_string_format_field_counts / sizeof *tds_string_format_field_counts; ++j) {
							if (tds_string_format_field_counts[j].type == new_format->type) {
								fields = tds_string_format_field_counts[j].fields;
								break;
							}
						}

						if (fields < 0) {
							tds_free(new_format);
							tds_logf(TDS_LOG_WARNING, "Unknown format specifier '%c' in string.\n", new_format->type);
							break;
						}

						++i;

						if (i + fields * 2 > readpos_len) {
							tds_free(new_format);
							tds_logf(TDS_LOG_WARNING, "Insufficient length for reading arguments to format string.\n");
							break;
						}

						for (int j = 0; j < fields; ++j) {
							char cur_field[3] = {0};

							cur_field[0] = readpos[i++];
							cur_field[1] = readpos[i++];

							new_format->fields[j] = strtol(cur_field, NULL, 16);
						}

						new_format->next = new_string_entry->str.formats;
						new_string_entry->str.formats = new_format;

						i--; /* Correct for last field having incremented the character. */
						continue;
					}

					if (i >= readpos_len) {
						break;
					}

					new_string_entry->str.data[new_string_entry->str.len++] = readpos[i];
				}

				new_string_entry->str.data[new_string_entry->str.len] = 0;

				new_string_entry->next = cur_offset->strings;
				cur_offset->strings = new_string_entry;
				cur_offset->string_count++;
			}

			break;
		case '!':
			break;
		default:
			tds_logf(TDS_LOG_WARNING, "Invalid format header '%c' in string database.\n", readbuf[0]);
			break;
		}
	}

	fclose(fd);

	tds_logf(TDS_LOG_MESSAGE, "Loaded %d string groups.\n", output->entry_count);
	return output;
}