//splits a string by a character static int _split_string_by_char(const char *str, int ch, ALLEGRO_USTR *result[], int result_len) { //start from the string beginning int pos = 0, next_pos; //count of sub-strings found int count = 0; //temp allegro string ALLEGRO_USTR_INFO temp_info; ALLEGRO_USTR *temp = al_ref_cstr(&temp_info, str); //iterate until the end of string for(;;) { //find the character next_pos = al_ustr_find_chr(temp, pos, ch); //if not found, end if (next_pos == -1) break; //add a string; if no more strings can be added, return if (!_add_substring(temp, pos, next_pos, result, result_len, &count)) goto END; //continue after the character pos = next_pos + al_utf8_width(ch); } //set the remainder of the string to be the last string in the array _add_substring(temp, pos, al_ustr_size(temp), result, result_len, &count); END: return count; }
/* [gtk thread] */ static gboolean create_native_message_box(gpointer data) { Msg *msg = data; ALLEGRO_DISPLAY *display = msg->display; ALLEGRO_NATIVE_DIALOG *fd = msg->dialog; GtkWidget *window; /* Create a new file selection widget */ GtkMessageType type = GTK_MESSAGE_INFO; GtkButtonsType buttons = GTK_BUTTONS_OK; if (fd->flags & ALLEGRO_MESSAGEBOX_YES_NO) type = GTK_MESSAGE_QUESTION; if (fd->flags & ALLEGRO_MESSAGEBOX_QUESTION) type = GTK_MESSAGE_QUESTION; if (fd->flags & ALLEGRO_MESSAGEBOX_WARN) type = GTK_MESSAGE_WARNING; if (fd->flags & ALLEGRO_MESSAGEBOX_ERROR) type = GTK_MESSAGE_ERROR; if (fd->flags & ALLEGRO_MESSAGEBOX_YES_NO) buttons = GTK_BUTTONS_YES_NO; if (fd->flags & ALLEGRO_MESSAGEBOX_OK_CANCEL) buttons = GTK_BUTTONS_OK_CANCEL; if (fd->mb_buttons) buttons = GTK_BUTTONS_NONE; window = gtk_message_dialog_new(NULL, 0, type, buttons, "%s", al_cstr(fd->mb_heading)); gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(window), "%s", al_cstr(fd->mb_text)); make_transient(display, window); if (fd->mb_buttons) { int i = 1; int pos = 0; while (1) { int next = al_ustr_find_chr(fd->mb_buttons, pos, '|'); int pos2 = next; if (next == -1) pos2 = al_ustr_size(fd->mb_buttons); ALLEGRO_USTR_INFO info; const ALLEGRO_USTR *button_text; button_text = al_ref_ustr(&info, fd->mb_buttons, pos, pos2); pos = pos2 + 1; char buffer[256]; al_ustr_to_buffer(button_text, buffer, sizeof buffer); gtk_dialog_add_button(GTK_DIALOG(window), buffer, i++); if (next == -1) break; } } gtk_window_set_title(GTK_WINDOW(window), al_cstr(fd->title)); g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(dialog_destroy), fd); g_signal_connect(G_OBJECT(window), "response", G_CALLBACK(msgbox_response), fd); g_signal_connect_swapped(G_OBJECT(window), "response", G_CALLBACK(gtk_widget_destroy), window); gtk_widget_show(window); return FALSE; }
/* _find_executable_file: * Helper function: searches path and current directory for executable. * Returns 1 on succes, 0 on failure. */ static ALLEGRO_PATH *_find_executable_file(const char *filename) { char *env; /* If filename has an explicit path, search current directory */ if (strchr(filename, '/')) { if (filename[0] == '/') { /* Full path; done */ return al_create_path(filename); } else { struct stat finfo; char pathname[1024]; /* Prepend current directory */ ALLEGRO_PATH *path = al_get_current_directory(); al_append_path_component(path, filename); if ((stat(pathname, &finfo)==0) && (!S_ISDIR (finfo.st_mode))) { return path; } } } /* If filename has no explicit path, but we do have $PATH, search * there */ else if ((env = getenv("PATH"))) { struct stat finfo; ALLEGRO_USTR *us = al_ustr_new(env); int start_pos = 0; while (start_pos >= 0) { int next_start_pos = al_ustr_find_chr(us, start_pos + 1, ':'); int end_pos = next_start_pos; if (next_start_pos < 0) end_pos = al_ustr_size(us); ALLEGRO_USTR_INFO info; ALLEGRO_USTR *sub = al_ref_ustr(&info, us, start_pos, end_pos); ALLEGRO_PATH *path = al_create_path_for_directory(al_cstr(sub)); al_append_path_component(path, filename); if (stat(al_path_cstr(path, '/'), &finfo) == 0 && !S_ISDIR (finfo.st_mode)) { return path; } start_pos = next_start_pos; } } return NULL; }
/* Test al_ustr_find_chr. */ static void t31(void) { ALLEGRO_USTR *us = al_ustr_new("aábdðeéfghiíaábdðeéfghií"); /* Find ASCII. */ CHECK(al_ustr_find_chr(us, 0, 'e') == 7); CHECK(al_ustr_find_chr(us, 7, 'e') == 7); /* start_pos is inclusive */ CHECK(al_ustr_find_chr(us, 8, 'e') == 23); CHECK(al_ustr_find_chr(us, 0, '.') == -1); /* Find non-ASCII. */ CHECK(al_ustr_find_chr(us, 0, U_eth) == 5); CHECK(al_ustr_find_chr(us, 5, U_eth) == 5); /* start_pos is inclusive */ CHECK(al_ustr_find_chr(us, 6, U_eth) == 21); CHECK(al_ustr_find_chr(us, 0, U_z_bar) == -1); al_ustr_free(us); }
/* parse_path_string: * * Parse a path string according to the following grammar. The last * component, if it is not followed by a directory separator, is interpreted * as the filename component, unless it is "." or "..". * * GRAMMAR * * path ::= "//" c+ "/" nonlast [Windows only] * | c ":" nonlast [Windows only] * | nonlast * * nonlast ::= c* "/" nonlast * | last * * last ::= "." * | ".." * | filename * * filename ::= c* [but not "." and ".."] * * c ::= any character but '/' */ static bool parse_path_string(const ALLEGRO_USTR *str, ALLEGRO_PATH *path) { ALLEGRO_USTR_INFO dot_info; ALLEGRO_USTR_INFO dotdot_info; const ALLEGRO_USTR * dot = al_ref_cstr(&dot_info, "."); const ALLEGRO_USTR * dotdot = al_ref_cstr(&dotdot_info, ".."); ALLEGRO_USTR *piece = al_ustr_new(""); int pos = 0; bool on_windows; /* We compile the drive handling code on non-Windows platforms to prevent * it becoming broken. */ #ifdef ALLEGRO_WINDOWS on_windows = true; #else on_windows = false; #endif if (on_windows) { /* UNC \\server\share name */ if (al_ustr_has_prefix_cstr(str, "//")) { int slash = al_ustr_find_chr(str, 2, '/'); if (slash == -1 || slash == 2) { /* Missing slash or server component is empty. */ goto Error; } al_ustr_assign_substr(path->drive, str, pos, slash); pos = slash + 1; } else { /* Drive letter. */ int colon = al_ustr_offset(str, 1); if (colon > -1 && al_ustr_get(str, colon) == ':') { /* Include the colon in the drive string. */ al_ustr_assign_substr(path->drive, str, 0, colon + 1); pos = colon + 1; } } } for (;;) { int slash = al_ustr_find_chr(str, pos, '/'); if (slash == -1) { /* Last component. */ al_ustr_assign_substr(piece, str, pos, al_ustr_size(str)); if (al_ustr_equal(piece, dot) || al_ustr_equal(piece, dotdot)) { al_append_path_component(path, al_cstr(piece)); } else { /* This might be an empty string, but that's okay. */ al_ustr_assign(path->filename, piece); } break; } /* Non-last component. */ al_ustr_assign_substr(piece, str, pos, slash); al_append_path_component(path, al_cstr(piece)); pos = slash + 1; } al_ustr_free(piece); return true; Error: al_ustr_free(piece); return false; }
static void ustr_replace_all(ALLEGRO_USTR *ustr, int32_t c1, int32_t c2) { for (int i = al_ustr_find_chr(ustr, 0, c1); i >= 0; i = al_ustr_find_chr(ustr, i, c1)) { al_ustr_set_chr(ustr, i, c2); } }