![]() |
|
[A5] for_each_file - missing |
PeKaGM
Member #15,654
June 2014
|
Hi to all.I'm trying to rewrite Allegro 4 code to Allegro 5 and I miss function - for_each_file - in A5. I found some routines on the net but they are not working. I have only little free time for programing so I can't study those routines for errors.Could someone tell me where can I find functional routine or some really simple way to replace function for_each_file in A5. I need to find all files in directory for example ".jpg" files and store their file names in a field of strings.Thank you very much. |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
Basically you al_create_fs_entry a filesystem entry for your desired directory, then you al_open_directory the directory, al_read_directory it until there are no entries left, and then al_close_directory it. Here is an example program that lists all the files in a given directory. You can specify the directory as a command line argument or else it will default to the current directory. 1
2#include "allegro5/allegro.h"
3
4#include <cstdio>
5#include <string>
6
7
8int main(int argc , char** argv) {
9
10 char* read_dir = 0;
11 bool free_dir = false;
12 bool close_dir = false;
13
14
15 if (!al_init()) {return 1;}
16
17 if (argc == 2) {
18 // Use first argument as read directory
19 read_dir = argv[1];
20 }
21 else {
22 // Use current directory as read directory
23 read_dir = al_get_current_directory();
24 free_dir = true;
25 }
26
27 ALLEGRO_FS_ENTRY* fs_dir_entry = al_create_fs_entry(read_dir);
28
29
30 unsigned int mode = al_get_fs_entry_mode(fs_dir_entry);
31
32 if (!(mode & ALLEGRO_FILEMODE_ISDIR)) {
33 printf("Invalid directory! (%s)\n" , read_dir);
34 }
35
36 if (!al_open_directory(fs_dir_entry)) {
37 printf("Could not open directory %s\n" , read_dir);
38 }
39 else {
40 /// Directory is now open
41 close_dir = true;
42
43 printf("Contents of directory %s\n" , read_dir);
44
45 // prime the while loop
46 ALLEGRO_FS_ENTRY* fs_entry = al_read_directory(fs_dir_entry);
47
48 // Loop until there are not more entries
49 while(fs_entry) {
50
51 // String manip to get short name of file/dir
52 std::string s = al_get_fs_entry_name(fs_entry);
53 std::string s2;
54 char path_sep = '\\';
55 if (s.find_first_of('/') != std::string::npos) {
56 path_sep = '/';
57 }
58 unsigned int last_separator = s.find_last_of(path_sep);
59 if (last_separator == std::string::npos) {
60 s2 = s;
61 }
62 else {
63 s2 = s.substr(s.find_last_of(path_sep) + 1);
64 }
65
66 // output short file/dir name
67 printf("%s\n" , s2.c_str());
68
69 al_destroy_fs_entry(fs_entry);
70
71 fs_entry = al_read_directory(fs_dir_entry);
72 }
73 }
74
75
76 if (close_dir) {
77 al_close_directory(fs_dir_entry);
78 }
79
80 if (fs_dir_entry) {
81 al_destroy_fs_entry(fs_dir_entry);
82 fs_dir_entry = 0;
83 }
84
85 if (free_dir) {
86 al_free(read_dir);
87 read_dir = 0;
88 }
89 return 0;
90}
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
beoran
Member #12,636
March 2011
|
Hmm, seeing that the code to replicate for_each_file is relatively long, I'm in favor of adding an al_for_each_file() function. |
Elias
Member #358
May 2000
|
beoran +1 -- |
Thomas Fjellstrom
Member #476
June 2000
![]() |
He could also use the ALLEGRO_PATH api to handle paths and files. Would cut out a bit of that code. -- |
Elias
Member #358
May 2000
|
Thomas Fjellstrom said: He could also use the ALLEGRO_PATH api to handle paths and files. Would cut out a bit of that code. Replace the loop with this then: 1while(fs_entry) {
2 ALLEGRO_PATH *path = al_create_path(al_get_fs_entry_name(fs_entry))
3 /* Note: ownership of the strings stays with path */
4 char const *name = al_get_path_filename(path)
5 if (not name[0]) {
6 /* Note: ownership of the strings stays with path */
7 name = al_get_path_component(path, -1);
8 }
9 if (strcmp(name, ".") != 0 && strcmp(name, "..") != 0) {
10 bool is_dir = al_get_fs_entry_mode(fs_entry) & ALLEGRO_FILEMODE_ISDIR
11
12 printf("%s%s\n", name, is_dir ? "/" : "");
13 }
14 /* Note: This also invalidates the name string. */
15 al_destroy_path(path)
16 al_destroy_fs_entry(fs_entry);
17 fs_entry = al_read_directory(fs_dir_entry);
18}
I also added directory detection, but it's still kinda longish. The proposed change would look something like: void callback(char const *filename, void *user) { printf("%s\n", filename); } al_for_each_file(read_dir, callback, int flags, user);
Which is much more simple Possible flags could be: -- |
beoran
Member #12,636
March 2011
|
Actually I already made a patch, with two functions, documentation and a test. One function uses a callback with char * file names and the other with ALLEGRO_FS_ENTRY. The flags parameter is a good idea though, I'll modify my patch to use that. I'll probably add the ALLEGRO_EACH_FILE_RECURSE, ALLEGRO_EACH_FILE_DIRECTORIES, ALLEGRO_EACH_FILE_DOTFILES and ALLEGRO_EACH_FILE_SHORT_PATH flags. The default call does not recurse, does not return directories, does return not dotfiles, and does return full file names, not partial ones, since full names are normally most useful. |
|