Ejemplo n.º 1
0
int main (int argc, char** argv)
{
  UnitTest t (17);

  // Ensure environment has no influence.
  unsetenv ("TASKDATA");
  unsetenv ("TASKRC");

  std::string ascii_text      = "This is a test";
  std::string utf8_text       = "más sábado miércoles";
  std::string utf8_wide_text  = "改变各种颜色";

  std::string ascii_text_color      = "This is a test";
  std::string utf8_text_color       = "más sábado miércoles";
  std::string utf8_wide_text_color  = "改变各种颜色";

  // unsigned int utf8_codepoint (const std::string&);
  t.is ((int) utf8_codepoint ("\\u0020"), 32, "\\u0020 --> ' '");
  t.is ((int) utf8_codepoint ("U+0020"),  32, "U+0020 --> ' '");

  // TODO unsigned int utf8_next_char (const std::string&, std::string::size_type&);
  // TODO std::string utf8_character (unsigned int);
  // TODO int utf8_sequence (unsigned int);

  // unsigned int utf8_length (const std::string&);
  t.is ((int) utf8_length (ascii_text),     14, "ASCII utf8_length");
  t.is ((int) utf8_length (utf8_text),      20, "UTF8 utf8_length");
  t.is ((int) utf8_length (utf8_wide_text),  6, "UTF8 wide utf8_length");

  // unsigned int utf8_width (const std::string&);
  t.is ((int) utf8_width (ascii_text),     14, "ASCII utf8_width");
  t.is ((int) utf8_width (utf8_text),      20, "UTF8 utf8_width");
  t.is ((int) utf8_width (utf8_wide_text), 12, "UTF8 wide utf8_width");

  // unsigned int utf8_text_length (const std::string&);
  t.is ((int) utf8_text_length (ascii_text_color),     14, "ASCII utf8_text_length");
  t.is ((int) utf8_text_length (utf8_text_color),      20, "UTF8 utf8_text_length");
  t.is ((int) utf8_text_length (utf8_wide_text_color),  6, "UTF8 wide utf8_text_length");

  // unsigned int utf8_text_width (const std::string&);
  t.is ((int) utf8_text_width (ascii_text_color),     14, "ASCII utf8_text_width");
  t.is ((int) utf8_text_width (utf8_text_color),      20, "UTF8 utf8_text_width");
  t.is ((int) utf8_text_width (utf8_wide_text_color), 12, "UTF8 wide utf8_text_width");

  // const std::string utf8_substr (const std::string&, unsigned int, unsigned int length = 0);
  t.is (utf8_substr (ascii_text, 0, 2),      "Th", "ASCII utf8_substr");
  t.is (utf8_substr (utf8_text, 0, 2),       "má", "UTF8 utf8_substr");
  t.is (utf8_substr (utf8_wide_text, 0, 2),  "改变", "UTF8 wide utf8_substr");

  return 0;
}
Ejemplo n.º 2
0
Archivo: draw.c Proyecto: phschoen/tig
static bool
draw_chars(struct view *view, enum line_type type, const char *string, int length,
	   int max_width, bool use_tilde)
{
	int len = 0;
	int col = 0;
	int trimmed = false;
	size_t skip = view->pos.col > view->col ? view->pos.col - view->col : 0;

	if (max_width <= 0)
		return VIEW_MAX_LEN(view) <= 0;

	len = utf8_length(&string, length, skip, &col, max_width, &trimmed, use_tilde, opt_tab_size);

	if (opt_iconv_out != ICONV_NONE) {
		string = encoding_iconv(opt_iconv_out, string, len);
		if (!string)
			return VIEW_MAX_LEN(view) <= 0;
	}

	set_view_attr(view, type);
	if (len > 0)
		waddnstr(view->win, string, len);

	if (trimmed && use_tilde) {
		set_view_attr(view, LINE_DELIMITER);
		waddstr(view->win, opt_truncation_delimiter ? opt_truncation_delimiter : "~");
		col++;
	}

	view->col += col;
	return VIEW_MAX_LEN(view) <= 0;
}
Ejemplo n.º 3
0
SV *
Drawable_get_text_box( Handle self, SV * text)
{
   gpARGS;
   Point * p;
   AV * av;
   int i;
   STRLEN dlen;
   char * c_text = SvPV( text, dlen);
   Bool   utf8 = prima_is_utf8_sv( text);
   if ( utf8) dlen = utf8_length(( U8*) c_text, ( U8*) c_text + dlen);
   gpENTER( newRV_noinc(( SV *) newAV()));
   p = apc_gp_get_text_box( self, c_text, dlen, utf8);
   gpLEAVE;

   av = newAV();
   if ( p) {
      for ( i = 0; i < 5; i++) {
         av_push( av, newSViv( p[ i]. x));
         av_push( av, newSViv( p[ i]. y));
      };
      free( p);
   }
   return newRV_noinc(( SV *) av);
}
Ejemplo n.º 4
0
int platform_enumerate_directories_begin(const utf8 *directory)
{
	enumerate_file_info *enumFileInfo;
	wchar_t *wpattern = utf8_to_widechar(directory);
	int length = min(utf8_length(directory), MAX_PATH);
	char *npattern = malloc(length+1);
	int converted;
	converted = wcstombs(npattern, wpattern, length);
	npattern[length - 1] = '\0';
	if (converted == MAX_PATH) {
		log_warning("truncated string %s", npattern);
	}
	log_verbose("begin directory listing, path: %s", npattern);

	// TODO: add some checking for stringness and directoryness

	int cnt;
	for (int i = 0; i < countof(_enumerateFileInfoList); i++) {
		enumFileInfo = &_enumerateFileInfoList[i];
		if (!enumFileInfo->active) {
			safe_strcpy(enumFileInfo->pattern, npattern, length);
			cnt = scandir(npattern, &enumFileInfo->fileListTemp, dirfilter, alphasort);
			if (cnt < 0)
			{
				break;
			}
			log_verbose("found %d files in dir '%s'", cnt, npattern);
			enumFileInfo->cnt = cnt;
			enumFileInfo->paths = malloc(cnt * sizeof(char *));
			char **paths = enumFileInfo->paths;
			// 256 is size of dirent.d_name
			const int buf_len = min(MAX_PATH, 256);
			const int dir_name_len = strnlen(npattern, MAX_PATH);
			char separator[] = {platform_get_path_separator(), 0};
			for (int idx = 0; idx < cnt; idx++)
			{
				struct dirent *d = enumFileInfo->fileListTemp[idx];
				const int entry_len = strnlen(d->d_name, MAX_PATH);
				// 1 for separator, 1 for trailing null
				size_t path_len = sizeof(char) * min(MAX_PATH, entry_len + dir_name_len + 2);
				paths[idx] = malloc(path_len);
				paths[idx][0] = '\0';
				log_verbose("dir_name: %s", npattern);
				strncat(paths[idx], npattern, path_len - 2);
				strncat(paths[idx], separator, path_len - strnlen(paths[idx], path_len) - 1);
				strncat(paths[idx], d->d_name, path_len - strnlen(paths[idx], path_len) - 1);
				log_verbose("paths[%d] = %s", idx, paths[idx]);
			}
			enumFileInfo->handle = 0;
			enumFileInfo->active = 1;
			free(wpattern);
			free(npattern);
			return i;
		}
	}

	free(wpattern);
	free(npattern);
	return -1;
}
Ejemplo n.º 5
0
void hkl_string_cat_utf8(HklString* string, const char* utf8_data)
{
  assert(string != NULL);
  assert(string->utf8_data != NULL);
  assert(utf8_data != NULL);

  size_t size = strlen(utf8_data);

  // The input string must be null-terminated
  assert(utf8_data[size] == '\0');

  // Resize the string to accomidate new data
  if (string->size < string->size + size + 1)
    string->utf8_data = realloc(string->utf8_data, string->size + size + 1);

  string->length += utf8_length(utf8_data);

  memcpy(string->utf8_data + string->size - 1, utf8_data, size + 1);

  string->size = string->size + size;

  // The string should have utf8_data
  assert(string->utf8_data != NULL);
  // The string must be NULL terminated by now
  assert(string->utf8_data[string->size - 1] == '\0');

  // The hash is invalid
  string->hash = 0;
}
Ejemplo n.º 6
0
void hkl_string_set_utf8(HklString* string, const char* utf8_data)
{
  assert(string != NULL);
  assert(utf8_data != NULL);

  size_t size = strlen(utf8_data);
  
  // The input string must be null-terminated
  assert(utf8_data[size] == '\0');

  // Resize the string to accomidate new data
  if (string->size < size + 1)
    string->utf8_data = realloc(string->utf8_data, size + 1);

  // This used to only copy size, but that caused a horrible memory leak
  string->size = size + 1;
  string->length = utf8_length(utf8_data);

  memcpy(string->utf8_data, utf8_data, size + 1);

  // The string should have utf8_data
  assert(string->utf8_data != NULL);
  // The string must be NULL terminated by now
  assert(string->utf8_data[size] == '\0');

  // The hash is invalid
  string->hash = 0;
}
Ejemplo n.º 7
0
HklString* hkl_string_new_from_stream(FILE* stream)
{
  // initialize an 8 character input buffer
  HklString* string = hkl_string_new_from_utf8("       ");
  size_t input = 0;
  int c;

  while (true)
  {
    c = fgetc(stdin);

    if (c == EOF || c == '\n')
      break;

    // if we are about to overflow
    if (input == string->size)
    {
      // double the buffer
      string->size *= 2;
      string->utf8_data = realloc(string->utf8_data, string->size);
    }

    string->utf8_data[input] = c;
    input++;
  }

  // write a null character
  string->utf8_data[input] = '\0';

  string->length = utf8_length(string->utf8_data);

  return string;
}
Ejemplo n.º 8
0
HklString* hkl_string_new_from_real(double real)
{
  HklString* string = hkl_string_new_from_utf8("               ");
  sprintf(string->utf8_data, "%lg", real);
  string->length = utf8_length(string->utf8_data);
  return string;
}
Ejemplo n.º 9
0
static bool
draw_text_overflow(struct view *view, const char *text, enum line_type type,
		   int overflow_length, int offset)
{
	bool on = overflow_length > 0;

	if (on) {
		int overflow = overflow_length + offset;
		int max = MIN(VIEW_MAX_LEN(view), overflow);
		const char *tmp = text;
		int text_width = 0;
		int trimmed = false;
		size_t len = utf8_length(&tmp, -1, 0, &text_width, max, &trimmed, false, 1);

		if (draw_text_expanded(view, type, text, -1, text_width, max < overflow))
			return true;

		text += len;
		type = LINE_OVERFLOW;
	}

	if (*text && draw_text(view, type, text))
		return true;

	return VIEW_MAX_LEN(view) <= 0;
}
Ejemplo n.º 10
0
Archivo: draw.c Proyecto: jlsandell/tig
static bool
draw_chars(struct view *view, enum line_type type, const char *string,
	   int max_len, bool use_tilde)
{
	int len = 0;
	int col = 0;
	int trimmed = FALSE;
	size_t skip = view->pos.col > view->col ? view->pos.col - view->col : 0;

	if (max_len <= 0)
		return VIEW_MAX_LEN(view) <= 0;

	if (opt_iconv_out != ICONV_NONE) {
		string = encoding_iconv(opt_iconv_out, string);
		if (!string)
			return VIEW_MAX_LEN(view) <= 0;
	}

	len = utf8_length(&string, skip, &col, max_len, &trimmed, use_tilde, opt_tab_size);

	set_view_attr(view, type);
	if (len > 0) {
		waddnstr(view->win, string, len);

		if (trimmed && use_tilde) {
			set_view_attr(view, LINE_DELIMITER);
			waddch(view->win, '~');
			col++;
		}
	}

	view->col += col;
	return VIEW_MAX_LEN(view) <= 0;
}
Ejemplo n.º 11
0
bool ssh_authenticate(void *sshclient, void *ht_username, void *ht_password) {
    /*
    	Since both the strings we get are HeavyThing strings, we can
    	convert them to std::string's first.
    */
    char *userbuf = (char *)malloc(string$utf8_length(ht_username)+1);
    userbuf[string$to_utf8(ht_username, userbuf)] = 0;
    char *passbuf = (char *)malloc(string$utf8_length(ht_password)+1);
    passbuf[string$to_utf8(ht_password, passbuf)] = 0;

    std::string user(userbuf);
    std::string pass(passbuf);

    std::cout << "Authenticating User: [" << user << "] Pass: [" << pass << "]" << std::endl;

    return true;
}
Ejemplo n.º 12
0
HklString* hkl_string_new_from_integer(int integer)
{
  // create a buffer to store the integer
  HklString* string = hkl_string_new_from_utf8("               ");
  sprintf(string->utf8_data,"%d", integer);
  string->length = utf8_length(string->utf8_data);
  return string;
}
Ejemplo n.º 13
0
int
utf8_width_of(const char *text, int max_bytes, int max_width)
{
	int text_width = 0;
	const char *tmp = text;
	int trimmed = false;

	utf8_length(&tmp, max_bytes, 0, &text_width, max_width, &trimmed, false, 1);
	return text_width;
}
Ejemplo n.º 14
0
Archivo: string.c Proyecto: avm/tig
int
utf8_width_max(const char *text, int max)
{
	int text_width = 0;
	const char *tmp = text;
	int trimmed = FALSE;

	utf8_length(&tmp, 0, &text_width, max, &trimmed, FALSE, 1);
	return text_width;
}
Ejemplo n.º 15
0
HklString* hkl_string_new_from_real(double real)
{
  // create a buffer to store the integer
  HklString* string = hkl_string_new();

  string->size = sprintf(conversion_buffer, "%lg", real) + 1;
  string->utf8_data = realloc(string->utf8_data, string->size);
  memcpy(string->utf8_data, conversion_buffer, string->size);
  string->length = utf8_length(string->utf8_data);

  return string;
}
Ejemplo n.º 16
0
bool platform_original_game_data_exists(const utf8 *path)
{
	wchar_t *wPath = utf8_to_widechar(path);
	int len = min(MAX_PATH, utf8_length(path));
	char buffer[MAX_PATH];
	wcstombs(buffer, wPath, len);
	buffer[len] = '\0';
	free(wPath);
	char checkPath[MAX_PATH];
	sprintf(checkPath, "%s%c%s%c%s", buffer, platform_get_path_separator(), "Data", platform_get_path_separator(), "g1.dat");
	return platform_file_exists(checkPath);
}
Ejemplo n.º 17
0
bool platform_file_exists(const utf8 *path)
{
	wchar_t *wPath = utf8_to_widechar(path);
	int len = min(MAX_PATH, utf8_length(path));
	char buffer[MAX_PATH];
	wcstombs(buffer, wPath, len);
	buffer[len] = '\0';
	free(wPath);
	bool exists = access(buffer, F_OK) != -1;
	log_warning("file '%s' exists = %i", buffer, exists);
	return exists;
}
Ejemplo n.º 18
0
Bool
Drawable_text_out( Handle self, SV * text, int x, int y)
{
   Bool ok;
   STRLEN dlen;
   char * c_text = SvPV( text, dlen);
   Bool   utf8 = prima_is_utf8_sv( text);
   if ( utf8) dlen = utf8_length(( U8*) c_text, ( U8*) c_text + dlen);
   ok = apc_gp_text_out( self, c_text, x, y, dlen, utf8);
   if ( !ok) perl_error();
   return ok;
}
Ejemplo n.º 19
0
int hkl_string_compare_utf8(HklString* string, const char* utf8_data)
{
  assert(string != NULL);
  assert(utf8_data != NULL);

  // Since we are doing a strncmp, we need to make sure we pick the larger
  // of the two strings as the size
  size_t ulen = utf8_length(utf8_data);
  size_t size = (string->length > ulen)?
    string->length : ulen;

  return strncmp(string->utf8_data, utf8_data, size);
}
Ejemplo n.º 20
0
Archivo: file.c Proyecto: 8l/aoeui
static void scan(struct view *view)
{
	char *raw, scratch[8];
	position_t at;
	size_t bytes = view_raw(view, &raw, 0, getpagesize());
	size_t chop = bytes < view->bytes ? 8 : 0;
	size_t chlen, check;
	Unicode_t ch, lastch = 0;
	int crnl = 0, nl = 0;
	Boolean_t any_tab = default_tabs;
	int tabstop = default_tab_stop;

	/* Reset state */
	view->text->flags &= ~(TEXT_NO_UTF8 | TEXT_CRNL | TEXT_NO_TABS);
	view->text->tabstop = default_tab_stop;

	if (utf8_mode == UTF8_NO)
		view->text->flags |= TEXT_NO_UTF8;
	else if (utf8_mode == UTF8_AUTO)
		for (at = 0; at + chop < bytes; at += chlen) {
			chlen = utf8_length(raw + at, bytes - at);
			ch = utf8_unicode(raw + at, chlen);
			check = unicode_utf8(scratch, ch);
			if (chlen != check) {
				view->text->flags |= TEXT_NO_UTF8;
				break;
			}
		}

	for (at = 0; at + chop < bytes; lastch = ch)
		if ((ch = view_unicode(view, at, &at)) == '\n') {
			nl++;
			crnl += lastch == '\r';
		}
	if (nl && crnl == nl)
		view->text->flags |= TEXT_CRNL;

	for (at = 0; at + chop < bytes; at = find_line_end(view, at) + 1) {
		int spaces = 0;
		while ((ch = view_unicode(view, at, &at)) == ' ')
			spaces++;
		if (ch == '\t')
			any_tab = TRUE;
		if (spaces > 1 && spaces < tabstop)
			tabstop = spaces;
	}
	if (default_no_tabs || !any_tab) {
		view->text->flags |= TEXT_NO_TABS;
		view->text->tabstop = tabstop;
	}
}
Ejemplo n.º 21
0
static bool compose_insert_delete(char** msg) {
    const char* const NONEMPTY_STRING = "abcこんにちは";
    const uint32_t insert_len = (uint32_t)utf8_length(NONEMPTY_STRING);

    ot_op* expected = ot_new_op();

    ot_op* op1 = ot_new_op();
    ot_insert(op1, NONEMPTY_STRING);

    ot_op* op2 = ot_new_op();
    ot_delete(op2, insert_len);

    return param_compose_test(op1, op2, expected, msg);
}
Ejemplo n.º 22
0
int
Drawable_get_text_width( Handle self, SV * text, Bool addOverhang)
{
   gpARGS;
   int res;
   STRLEN dlen;
   char * c_text = SvPV( text, dlen);
   Bool   utf8 = prima_is_utf8_sv( text);
   if ( utf8) dlen = utf8_length(( U8*) c_text, ( U8*) c_text + dlen);
   gpENTER(0);
   res = apc_gp_get_text_width( self, c_text, dlen, addOverhang, utf8);
   gpLEAVE;
   return res;
}
Ejemplo n.º 23
0
bool platform_ensure_directory_exists(const utf8 *path)
{
	mode_t mask = getumask();

	wchar_t *wPath = utf8_to_widechar(path);
	int len = min(MAX_PATH, utf8_length(path));
	char buffer[MAX_PATH];
	wcstombs(buffer, wPath, len);
	buffer[len - 1] = '\0';
	free(wPath);
	log_verbose("%s", buffer);
	const int result = mkdir(buffer, mask);
	if (result == 0 || (result == -1 && errno == EEXIST))
		return true;
	return false;
}
Ejemplo n.º 24
0
static int 
tokenize_indic_text(varnam *handle,
                    const char *input,
                    struct strbuf *string)
{
    const char *remaining;
    int counter = 0, input_len = 0;
    size_t matchpos = 0;
    /* struct varnam_internal *vi;        */
    char lookup[100], match[100];
    struct token *temp = NULL, *last = NULL;

    /* vi = handle->internal; */
    match[0] = '\0';

    input_len = utf8_length (input);
    while (counter < input_len) 
    {
        substr (lookup, input, 1, ++counter);
        temp = find_rtl_token (handle, lookup);
        if (temp) {
            last = temp;
            matchpos = strlen (lookup);
            strncpy(match, lookup, 100);
        }
        else if( !can_find_rtl_token( handle, last, lookup )) { 
            break;
        }
    }

    if (last) 
    {
        resolve_rtl_token (handle, match, last, string);
        remaining = input + matchpos;
        set_last_rtl_token (handle, last);
    }
    else {
        strbuf_add (string, lookup);
        remaining = input + 1;
        set_last_rtl_token (handle, NULL);
    }

    if (strlen (remaining) > 0)
        return tokenize_indic_text (handle, remaining, string);

    return VARNAM_SUCCESS;
}
Ejemplo n.º 25
0
bool platform_directory_exists(const utf8 *path)
{
	wchar_t *wPath = utf8_to_widechar(path);
	int len = min(MAX_PATH, utf8_length(path));
	char buffer[MAX_PATH];
	wcstombs(buffer, wPath, len);
	buffer[len] = '\0';
	free(wPath);
	struct stat dirinfo;
	int result = stat(buffer, &dirinfo);
	log_verbose("checking dir %s, result = %d, is_dir = %d", buffer, result, S_ISDIR(dirinfo.st_mode));
	if ((result != 0) || !S_ISDIR(dirinfo.st_mode))
	{
		return false;
	}
	return true;
}
Ejemplo n.º 26
0
/**
 * Insert text into the text area
 *
 * \param self Text area
 * \param index 0-based character index to insert at
 * \param text UTF-8 text to insert
 */
void ro_textarea_insert_text(uintptr_t self, unsigned int index,
		const char *text)
{
	struct text_area *ta;
	unsigned int b_len = strlen(text);
	size_t b_off, c_len;

	ta = (struct text_area *)self;
	if (!ta || ta->magic != MAGIC) {
		LOG(("magic doesn't match"));
		return;
	}

	c_len = utf8_length(ta->text);

	/* Find insertion point */
	if (index > c_len)
		index = c_len;

	for (b_off = 0; index-- > 0;
			b_off = utf8_next(ta->text, ta->text_len, b_off))
		; /* do nothing */

	if (b_len + ta->text_len >= ta->text_alloc) {
		char *temp = realloc(ta->text, b_len + ta->text_len + 64);
		if (!temp) {
			LOG(("realloc failed"));
			return;
		}

		ta->text = temp;
		ta->text_alloc = b_len + ta->text_len + 64;
	}

	/* Shift text following up */
	memmove(ta->text + b_off + b_len, ta->text + b_off,
			ta->text_len - b_off);
	/* Insert new text */
	memcpy(ta->text + b_off, text, b_len);

	ta->text_len += b_len;

	/** \todo calculate line to reflow from */
	ro_textarea_reflow(ta, 0);
}
Ejemplo n.º 27
0
static bool compose_insert_insert(char** msg) {
    const char* const INSERT1 = "defこんにちは";
    const char* const INSERT2 = "abcこんにちは";
    const uint32_t insert2_len = (uint32_t)utf8_length(INSERT2);
    const char* const EXPECTED_INSERT = "abcこんにちはdefこんにちは";

    ot_op* expected = ot_new_op();
    ot_insert(expected, EXPECTED_INSERT);

    ot_op* op1 = ot_new_op();
    ot_insert(op1, INSERT1);

    ot_op* op2 = ot_new_op();
    ot_insert(op2, INSERT2);
    ot_skip(op2, insert2_len);

    return param_compose_test(op1, op2, expected, msg);
}
Ejemplo n.º 28
0
static void utterance_parse (utterance *utt)
{
    int i, j, whitespace;
    
    utt->letters [0] = LETTER_PAU;
    i = 0; j = 1; whitespace = 1;
    
    while (utt->text[i] != 0 && i < STR_SIZE)
	{	
	    if (utt->text[i] == '-' ||
		utt->text[i] == '\''
		) {
		i++;
		continue;
	    }
	    if (utt->text[i] == ' ' ||
		utt->text[i] == '_' ||
		utt->text[i] == '\"' ||
		utt->text[i] == '\t' ||
		utt->text[i] == '\n') {
		i++;
		if (!whitespace) {
		        utt->letters[j] = LETTER_PAU;
		        j++;
		        whitespace = 1;
		}
		continue;
	    }
	    if (utt->text[i] > 'z' || utt->text[i] < 'A') {
		i++;
		continue;
	    }
		
	    utt->letters[j] = get_letter_index (utt, i);
	    i += utf8_length(utt->text + i);
	    j ++;
	    whitespace = 0;
	}
    if (whitespace == 0)
        utt->letters[j] = LETTER_PAU;
}
Ejemplo n.º 29
0
metastring *
NewMetaString(unsigned char *init_str)
{
    metastring *s;
    unsigned char empty_string[] = "";

    META_MALLOC(s, 1, metastring);
    assert( s != NULL );

    if (init_str == NULL)
	init_str = empty_string;
    s->length  = utf8_length(init_str, init_str+strlen((char*)init_str));
    /* preallocate a bit more for potential growth */
    s->bufsize = s->length + 7;

    META_MALLOC(s->str, s->bufsize, unsigned char);
    assert( s->str != NULL );
    
    strncpy((char*)s->str, (char*)init_str, s->length + 1);
    s->free_string_on_destroy = 1;

    return s;
}
Ejemplo n.º 30
0
int platform_enumerate_files_begin(const utf8 *pattern)
{
	enumerate_file_info *enumFileInfo;
	wchar_t *wpattern = utf8_to_widechar(pattern);
	int length = min(utf8_length(pattern), MAX_PATH);
	char *npattern = malloc(length);
	int converted;
	converted = wcstombs(npattern, wpattern, length);
	npattern[length - 1] = '\0';
	if (converted == MAX_PATH) {
		log_warning("truncated string %s", npattern);
	}
	log_warning("begin file search, pattern: %s", npattern);

	char *file_name = strrchr(npattern, platform_get_path_separator());
	char *dir_name;
	if (file_name != NULL)
	{
		dir_name = strndup(npattern, file_name - npattern);
		file_name = &file_name[1];
	} else {
		file_name = npattern;
		dir_name = strdup(".");
	}

	char *smatch = strchr(file_name, '*');
	if ((smatch != file_name) && (smatch != NULL))
	{
		log_error("Sorry, can only match '*' at start of filename.");
		return -1;
	} else {
		// '*' found
		if (smatch != NULL)
		{
			// some boundary checking needed
			// skip the '*'
			smatch = &smatch[1];
			char *match2 = strchr(&smatch[1], '*');
			if (match2 != NULL)
			{
				log_error("Sorry, can only match one '*' wildcard.");
				return -1;
			}
		} else {
			// '*' not found
			smatch = file_name;
		}
	}
	char *qmatch = strchr(file_name, '?');
	if ((qmatch != &npattern[length - 1]) && (qmatch != NULL))
	{
		log_error("Sorry, can only match '?' at end of filename.");
		return -1;
	} else {
		qmatch = &npattern[length];
	}
	int pattern_length = qmatch - smatch;
	g_file_pattern = strndup(smatch, pattern_length);
	for (int j = 0; j < pattern_length; j++)
	{
		g_file_pattern[j] = (char)toupper(g_file_pattern[j]);
	}
	log_warning("looking for file matching %s", g_file_pattern);
	int cnt;
	for (int i = 0; i < countof(_enumerateFileInfoList); i++) {
		enumFileInfo = &_enumerateFileInfoList[i];
		if (!enumFileInfo->active) {
			safe_strncpy(enumFileInfo->pattern, npattern, length);
			cnt = scandir(dir_name, &enumFileInfo->fileListTemp, winfilter, alphasort);
			if (cnt < 0)
			{
				break;
			}
			log_warning("found %d files matching in dir '%s'", cnt, dir_name);
			enumFileInfo->cnt = cnt;
			enumFileInfo->paths = malloc(cnt * sizeof(char *));
			char **paths = enumFileInfo->paths;
			// 256 is size of dirent.d_name
			const int buf_len = min(MAX_PATH, 256);
			const int dir_name_len = strnlen(dir_name, MAX_PATH);
			char separator[] = {platform_get_path_separator(), 0};
			for (int idx = 0; idx < cnt; idx++)
			{
				struct dirent *d = enumFileInfo->fileListTemp[idx];
				const int entry_len = strnlen(d->d_name, MAX_PATH);
				// 1 for separator, 1 for trailing null
				paths[idx] = malloc(sizeof(char) * min(MAX_PATH, entry_len + dir_name_len + 2));
				paths[idx][0] = '\0';
				log_verbose("dir_name: %s", dir_name);
				strncat(paths[idx], dir_name, MAX_PATH);
				strncat(paths[idx], separator, MAX_PATH);
				strncat(paths[idx], d->d_name, MAX_PATH);
				log_verbose("paths[%d] = %s", idx, paths[idx]);
			}
			enumFileInfo->handle = 0;
			enumFileInfo->active = 1;
			free(dir_name);
			free(g_file_pattern);
			g_file_pattern = NULL;
			free(wpattern);
			free(npattern);
			return i;
		}
	}

	free(dir_name);
	free(g_file_pattern);
	g_file_pattern = NULL;
	free(wpattern);
	free(npattern);
	return -1;
}