wlt: fix shl_hook API changes
[platform/upstream/kmscon.git] / src / genshader.c
1 /*
2  * kmscon - Generate Shader Files
3  *
4  * Copyright (c) 2011-2012 David Herrmann <dh.herrmann@googlemail.com>
5  * Copyright (c) 2011 University of Tuebingen
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining
8  * a copy of this software and associated documentation files
9  * (the "Software"), to deal in the Software without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sublicense, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included
16  * in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  */
26
27 /*
28  * Shader Generator
29  * This takes as arguments shaders and creates a C-source file which
30  * contains these shaders as constants.
31  */
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36
37 static char *read_file(const char *path, size_t *size)
38 {
39         FILE *ffile;
40         ssize_t len;
41         char *buf;
42
43         ffile = fopen(path, "rb");
44         if (!ffile) {
45                 fprintf(stderr, "genshader: cannot open %s: %m\n", path);
46                 abort();
47         }
48
49         if (fseek(ffile, 0, SEEK_END) != 0) {
50                 fprintf(stderr, "genshader: cannot seek %s: %m\n", path);
51                 abort();
52         }
53
54         len = ftell(ffile);
55         if (len < 0) {
56                 fprintf(stderr, "genshader: cannot tell %s: %m\n", path);
57                 abort();
58         }
59
60         if (len < 1) {
61                 fprintf(stderr, "genshader: empty file %s\n", path);
62                 abort();
63         }
64
65         rewind(ffile);
66
67         buf = malloc(len + 1);
68         if (!buf) {
69                 fprintf(stderr, "genshader: memory allocation failed\n");
70                 abort();
71         }
72
73         if (len != fread(buf, 1, len, ffile)) {
74                 fprintf(stderr, "genshader: cannot read %s: %m\n", path);
75                 abort();
76         }
77
78         buf[len] = 0;
79         *size = len;
80         fclose(ffile);
81
82         return buf;
83 }
84
85 static const char *get_basename(const char *path)
86 {
87         const char *res;
88
89         res = strrchr(path, '/');
90         if (!res || !*++res)
91                 return path;
92
93         return res;
94 }
95
96 static void write_seq(FILE *out, const char *src, size_t len)
97 {
98         size_t i;
99
100         for (i = 0; i < len; ++i) {
101                 if (src[i] == '\n') {
102                         fwrite("\\n\"\n\"", 5, 1, out);
103                 } else if (src[i] == '"') {
104                         fwrite("\\\"", 2, 1, out);
105                 } else {
106                         fwrite(&src[i], 1, 1, out);
107                 }
108         }
109 }
110
111 static void write_name(FILE *out, const char *name)
112 {
113         size_t i, len;
114
115         len = strlen(name);
116         for (i = 0; i < len; ++i) {
117                 if ((name[i] >= 'A' && name[i] <= 'Z') ||
118                     (name[i] >= 'a' && name[i] <= 'z') ||
119                     (name[i] >= '0' && name[i] <= '9'))
120                         fwrite(&name[i], 1, 1, out);
121                 else
122                         fwrite("_", 1, 1, out);
123         }
124 }
125
126 static void write_single_file(FILE *out, const char *path)
127 {
128         static const char c1[] = "const char *gl_";
129         static const char c2[] = " = \"";
130         static const char c3[] = "\";\n";
131         const char *name;
132         char *content;
133         size_t len;
134
135         name = get_basename(path);
136         content = read_file(path, &len);
137
138         fwrite(c1, sizeof(c1) - 1, 1, out);
139         write_name(out, name);
140         fwrite(c2, sizeof(c2) - 1, 1, out);
141         write_seq(out, content, len);
142         fwrite(c3, sizeof(c3) - 1, 1, out);
143
144         free(content);
145 }
146
147 int main(int argc, char *argv[])
148 {
149         FILE *out;
150         size_t i;
151         static const char c0[] = "/* This file was generated "
152                                  "by genshader.c */\n";
153
154         if (argc < 2) {
155                 fprintf(stderr, "genshader: use ./genshader <outputfile> [<shader-files> ...]\n");
156                 abort();
157         }
158
159         out = fopen(argv[1], "wb");
160         if (!out) {
161                 fprintf(stderr, "genshader: cannot open %s: %m\n", argv[1]);
162                 abort();
163         }
164
165         fwrite(c0, sizeof(c0) - 1, 1, out);
166         for (i = 2; i < argc; ++i) {
167                 write_single_file(out, argv[i]);
168         }
169
170         fclose(out);
171
172         return EXIT_SUCCESS;
173 }