/* Test al_ustr_assign_cstr. */ static void t41(void) { ALLEGRO_USTR *us1 = al_ustr_new("Моја лебдилица је пуна јегуља"); ALLEGRO_USTR *us2 = al_ustr_new(""); CHECK(al_ustr_assign_substr(us2, us1, 9, 27)); CHECK(0 == strcmp(al_cstr(us2), "лебдилица")); /* Start > End */ CHECK(al_ustr_assign_substr(us2, us1, 9, 0)); CHECK(0 == strcmp(al_cstr(us2), "")); /* Start, end out of bounds */ CHECK(al_ustr_assign_substr(us2, us1, -INT_MAX, INT_MAX)); CHECK(0 == strcmp(al_cstr(us2), "Моја лебдилица је пуна јегуља")); al_ustr_free(us1); al_ustr_free(us2); }
/* Function: al_get_path_basename */ const char *al_get_path_basename(const ALLEGRO_PATH *path) { int dot; ASSERT(path); dot = al_ustr_rfind_chr(path->filename, al_ustr_size(path->filename), '.'); if (dot >= 0) { al_ustr_assign_substr(path->basename, path->filename, 0, dot); return al_cstr(path->basename); } return al_cstr(path->filename); }
/* 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; }