Merged older cs.po file with newest pot file.
[gliv/czech_localization.git] / src / foreach_file.c
blob05e6704922315060e8cc89ae8980a2f4e3c03903
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 * See the COPYING file for license information.
18 * Guillaume Chazarain <guichaz@yahoo.fr>
21 /*****************************************
22 * A simplified ftw(3), specific to GLiv *
23 *****************************************/
25 #include <sys/stat.h> /* struct stat, stat() */
26 #include <dirent.h> /* struct dirent, *dir() */
27 #include <stdio.h> /* perror() */
29 #include "gliv.h"
30 #include "foreach_file.h"
31 #include "pathset.h"
33 /* Push directories and handle files. */
34 static GSList *process_dir(GSList * stack, const gchar * dirname,
35 foreach_file_func func, gint * res)
37 DIR *dir;
38 struct dirent *dir_ent;
39 struct stat st;
40 gchar *name, *fullname;
41 gboolean is_dir = FALSE, is_dir_known;
43 dir = opendir(dirname);
44 if (dir == NULL) {
45 perror(dirname);
46 return stack;
49 while ((dir_ent = readdir(dir)) != NULL) {
50 name = dir_ent->d_name;
52 if (name[0] == '.' &&
53 (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')))
54 /* Skip "." and "..". */
55 continue;
57 fullname = g_build_filename(dirname, name, NULL);
58 is_dir_known = FALSE;
60 #ifdef _DIRENT_HAVE_D_TYPE
61 switch (dir_ent->d_type) {
62 case DT_UNKNOWN:
63 case DT_LNK:
64 break;
66 case DT_DIR:
67 is_dir = TRUE;
68 is_dir_known = TRUE;
69 break;
71 default:
72 is_dir = FALSE;
73 is_dir_known = TRUE;
74 break;
76 #endif
78 if (is_dir_known == FALSE && !stat(fullname, &st)) {
79 is_dir = S_ISDIR(st.st_mode);
80 is_dir_known = TRUE;
83 if (is_dir_known) {
84 if (is_dir)
85 /* A directory. */
86 stack = g_slist_prepend(stack, fullname);
87 else {
88 /* A file. */
89 *res += (*func) (fullname);
90 g_free(fullname);
95 closedir(dir);
96 return stack;
100 * We know that func is add_file_to_list and
101 * we return the number of inserted files.
103 gint foreach_file(const gchar * path, foreach_file_func func)
105 GSList *stack = NULL;
106 gchar *current;
107 struct pathset *set;
108 struct stat st;
109 gint res = 0;
111 if (stat(path, &st) < 0) {
112 /* The path is not usable. */
113 perror(path);
114 return 0;
117 if (S_ISDIR(st.st_mode) == FALSE)
118 /* The path is a file, not a directory. */
119 return (*func) (path);
121 /* The path is a valid directory. */
123 stack = g_slist_prepend(stack, g_strdup(path)); /* push */
125 set = pathset_new();
127 while (stack) {
128 current = stack->data;
129 stack = g_slist_remove_link(stack, stack); /* pop */
131 if (!stat(current, &st) && pathset_add(set, current))
132 /* Not already scanned. */
133 stack = process_dir(stack, current, func, &res);
135 g_free(current);
138 pathset_free(set);
140 return res;