Tizen 2.1 base
[framework/uifw/ecore.git] / src / lib / ecore_desktop / ecore_desktop_xmlame.c
1 #include "Ecore_Desktop.h"
2 #include "ecore_desktop_private.h"
3
4 #include <fcntl.h>
5 #include <ctype.h>
6 #include <sys/stat.h>
7
8 /** xmlame.c Extensively Mocked Language Approximately Mangled for Enlightenment. 
9  *
10  * This is NOT a real XML parser.  There were a few ways we could go when it came
11  * to parsing the freedesktop.org (fdo) XML menu files.  Whatever way we went, we 
12  * needed some sort of XML parser if we wanted to fully support fdo menu files.  
13  * Nothing we can do about that, fdo set the standard and they choose XML to do it.
14  *
15  * After a discussion with raster, three things led to the decision to do it this 
16  * way.  It is likely that this will get included as a core part of the E17 window 
17  * manager (E17) coz E17 needs this functionality.  E17 is in a dependency freeze
18  * and there is no XML parser in it's current dependencies.  The fdo XML menu files
19  * look to be simple enough to parse that this sort of fake, brain dead, XML parser
20  * may get away with it.  Much testing on lots of systems is highly recommended.
21  *
22  * The final '>' of a tag is replaced with a '\0', but it's existance can be implied.
23  */
24
25 static char        *_ecore_desktop_xmlame_parse(Ecore_Desktop_Tree * tree,
26                                                 char *buffer);
27
28 Ecore_Desktop_Tree *
29 ecore_desktop_xmlame_new(char *buffer)
30 {
31    Ecore_Desktop_Tree *tree;
32
33    tree = ecore_desktop_tree_new(buffer);
34    return tree;
35 }
36
37 Ecore_Desktop_Tree *
38 ecore_desktop_xmlame_get(char *file)
39 {
40    int                 size;
41    char               *buffer;
42    Ecore_Desktop_Tree *tree = NULL;
43
44    size = ecore_file_size(file);
45    buffer = (char *)malloc(size + 1);
46    if (buffer)
47      {
48         int                 fd;
49
50         buffer[0] = '\0';
51         fd = open(file, O_RDONLY);
52         if (fd != -1)
53           {
54              if (read(fd, buffer, size) == size)
55                 buffer[size] = '\0';
56           }
57         tree = ecore_desktop_xmlame_new(buffer);
58         if (tree)
59           {
60              /* Have the file name as the first item on the tree, for later reference. */
61              ecore_desktop_tree_extend(tree, file);
62              _ecore_desktop_xmlame_parse(tree, buffer);
63           }
64      }
65    return tree;
66 }
67
68 static char        *
69 _ecore_desktop_xmlame_parse(Ecore_Desktop_Tree * tree, char *buffer)
70 {
71    while (*buffer != '\0')
72      {
73         char               *text;
74
75         /* Skip any white space at the beginning. */
76         while ((*buffer != '\0') && (isspace(*buffer)))
77            buffer++;
78         text = buffer;
79         /* Find the beginning of a tag. */
80         while ((*buffer != '<') && (*buffer != '\0'))
81            buffer++;
82         /* Check for data between tags. */
83         if (buffer != text)
84           {
85              char                t;
86
87              t = *buffer;
88              *buffer = '\0';
89              ecore_desktop_tree_extend(tree, text);
90              *buffer = t;
91           }
92         if (*buffer != '\0')
93           {
94              char               *begin;
95
96              begin = buffer++;
97              /* Find the end of the tag. */
98              while ((*buffer != '>') && (*buffer != '\0'))
99                 buffer++;
100              /* We have our tag, do something with it. */
101              if (*buffer != '\0')
102                {
103                   *buffer++ = '\0';
104                   if (begin[1] == '/')
105                     {           /* The end of an element. */
106                        ecore_desktop_tree_add(tree, begin);
107                        break;
108                     }
109                   else if ((begin[1] == '!') || (begin[1] == '-')
110                            || (*(buffer - 2) == '/'))
111                     {           /* This is a script, a comment, or a stand alone tag. */
112                        ecore_desktop_tree_add(tree, begin);
113                     }
114                   else
115                     {           /* The beginning of an element. */
116                        Ecore_Desktop_Tree *new_tree;
117
118                        new_tree = ecore_desktop_xmlame_new(NULL);
119                        if (new_tree)
120                          {
121                             ecore_desktop_tree_add_child(tree, new_tree);
122                             ecore_desktop_tree_add(new_tree, begin);
123                             buffer =
124                                _ecore_desktop_xmlame_parse(new_tree, buffer);
125                          }
126                     }
127                }
128           }
129      }
130
131    return buffer;
132 }