check alloc
[dos_imgv] / imago / src / ftmodule.c
1 /*
2 libimago - a multi-format image file input/output library.
3 Copyright (C) 2010 John Tsiombikas <nuclear@member.fsf.org>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published
7 by the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <stdlib.h>
20 #include <string.h>
21 #include "ftmodule.h"
22 #include "chkalloc.h"
23
24 static struct list_node {
25         struct ftype_module *module;
26         struct list_node *next;
27 } *modules;
28
29 /* defined in modules.c which is generated by configure */
30 void img_modules_init();
31
32 static int done_init;
33
34 int img_register_module(struct ftype_module *mod)
35 {
36         struct list_node *node;
37
38         if(!(node = chk_malloc(sizeof *node))) {
39                 return -1;
40         }
41
42         node->module = mod;
43         node->next = modules;
44         modules = node;
45         return 0;
46 }
47
48 struct ftype_module *img_find_format_module(struct img_io *io)
49 {
50         struct list_node *node;
51
52         if(!done_init) {
53                 img_modules_init();
54                 done_init = 1;
55         }
56
57         node = modules;
58         while(node) {
59                 if(node->module->check(io) != -1) {
60                         return node->module;
61                 }
62                 node = node->next;
63         }
64         return 0;
65 }
66
67 struct ftype_module *img_guess_format(const char *fname)
68 {
69         struct list_node *node;
70         char *suffix;
71         int suffix_len;
72
73         if(!done_init) {
74                 img_modules_init();
75                 done_init = 1;
76         }
77
78         if(!(suffix = strrchr(fname, '.'))) {
79                 return 0;       /* no suffix, can't guess ... */
80         }
81         suffix_len = (int)strlen(suffix);
82
83         node = modules;
84         while(node) {
85                 char *suflist = node->module->suffix;
86                 char *start, *end;
87
88                 while(*suflist) {
89                         if(!(start = strstr(suflist, suffix))) {
90                                 break;
91                         }
92                         end = start + suffix_len;
93
94                         if(*end == ':' || *end == 0) {
95                                 return node->module;    /* found it */
96                         }
97                         suflist = end;
98                 }
99
100                 node = node->next;
101         }
102         return 0;
103 }
104
105 struct ftype_module *img_get_module(int idx)
106 {
107         struct list_node *node;
108
109         if(!done_init) {
110                 img_modules_init();
111                 done_init = 1;
112         }
113
114         node = modules;
115         while(node && idx--) {
116                 node = node->next;
117         }
118         return node ? node->module : 0;
119 }