]> git.sur5r.net Git - cc65/blob - src/sp65/c.c
Added two more conversion targets: geos-bitmap, which will create a GEOS
[cc65] / src / sp65 / c.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                    c.c                                    */
4 /*                                                                           */
5 /*              C output for the sp65 sprite and bitmap utility              */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 2012,      Ullrich von Bassewitz                                      */
10 /*                Roemerstrasse 52                                           */
11 /*                D-70794 Filderstadt                                        */
12 /* EMail:         uz@cc65.org                                                */
13 /*                                                                           */
14 /*                                                                           */
15 /* This software is provided 'as-is', without any expressed or implied       */
16 /* warranty.  In no event will the authors be held liable for any damages    */
17 /* arising from the use of this software.                                    */
18 /*                                                                           */
19 /* Permission is granted to anyone to use this software for any purpose,     */
20 /* including commercial applications, and to alter it and redistribute it    */
21 /* freely, subject to the following restrictions:                            */
22 /*                                                                           */
23 /* 1. The origin of this software must not be misrepresented; you must not   */
24 /*    claim that you wrote the original software. If you use this software   */
25 /*    in a product, an acknowledgment in the product documentation would be  */
26 /*    appreciated but is not required.                                       */
27 /* 2. Altered source versions must be plainly marked as such, and must not   */
28 /*    be misrepresented as being the original software.                      */
29 /* 3. This notice may not be removed or altered from any source              */
30 /*    distribution.                                                          */
31 /*                                                                           */
32 /*****************************************************************************/
33
34
35
36 #include <errno.h>
37 #include <stdio.h>
38 #include <string.h>
39
40 /* common */
41 #include "chartype.h"
42 #include "check.h"
43 #include "cmdline.h"
44 #include "version.h"
45
46 /* sp65 */
47 #include "attr.h"
48 #include "c.h"
49 #include "error.h"
50
51
52
53 /*****************************************************************************/
54 /*                                   Code                                    */
55 /*****************************************************************************/
56
57
58
59 static int ValidIdentifier (const char* L)
60 /* Check a C identifier for validity */
61 {
62     /* Must begin with underscore or alphabetic character */
63     if (*L != '_' && !IsAlpha (*L)) {
64         return 0;
65     }
66     ++L;
67
68     /* Remainder must be as above plus digits */
69     while (*L) {
70         if (*L != '_' && !IsAlNum (*L)) {
71             return 0;
72         }
73         ++L;
74     }
75
76     /* Ok */
77     return 1;
78 }
79
80
81
82 static unsigned GetBytesPerLine (const Collection* A)
83 /* Return the number of bytes per line from the attribute collection A */
84 {
85     char        C;
86     unsigned    BytesPerLine = 16;
87
88     /* Check for a bytesperline attribute */
89     const char* V = GetAttrVal (A, "bytesperline");
90     if ((V && sscanf (V, "%u%c", &BytesPerLine, &C) != 1) ||
91         (BytesPerLine < 1 || BytesPerLine > 64)) {
92         Error ("Invalid value for attribute `bytesperline'");
93     }
94     return BytesPerLine;
95 }
96
97
98
99 static unsigned GetBase (const Collection* A)
100 /* Return the number base from the attribute collection A */
101 {
102     char        C;
103     unsigned    Base = 16;
104
105     /* Check for a base attribute */
106     const char* V = GetAttrVal (A, "base");
107     if ((V && sscanf (V, "%u%c", &Base, &C) != 1) || (Base != 10 && Base != 16)) {
108         Error ("Invalid value for attribute `base'");
109     }
110     return Base;
111 }
112
113
114
115 static const char* GetIdentifier (const Collection* A)
116 /* Return the variable identifier from the attribute collection A */
117 {
118     /* Check for a ident attribute */
119     const char* Ident = NeedAttrVal (A, "ident", "write");
120     if (!ValidIdentifier (Ident)) {
121         Error ("Invalid value for attribute `ident'");
122     }
123     return Ident;
124 }
125
126
127
128 void WriteCFile (const StrBuf* Data, const Collection* A)
129 /* Write the contents of Data to a file in C format */
130 {
131     FILE*       F;
132     const char* D;
133     unsigned    Size;
134
135
136     /* Get the file name */
137     const char* Name = NeedAttrVal (A, "name", "write");
138
139     /* Check the number of bytes per line */
140     unsigned BytesPerLine = GetBytesPerLine (A);
141
142     /* Get the number base */
143     unsigned Base = GetBase (A);
144
145     /* Get the identifier */
146     const char* Ident = GetIdentifier (A);
147
148     /* Open the output file */
149     F = fopen (Name, "w");
150     if (F == 0) {
151         Error ("Cannot open output file `%s': %s", Name, strerror (errno));
152     }
153
154     /* Write a readable header */
155     fprintf (F,
156              "/*\n"
157              " * This file was generated by %s %s\n"
158              " */\n"
159              "\n",
160              ProgName,
161              GetVersionAsString ());
162
163
164     /* Output the declaration and identifier */
165     fprintf (F, "const unsigned char %s[] = {\n", Ident);
166
167     /* Write the data */
168     D    = SB_GetConstBuf (Data);
169     Size = SB_GetLen (Data);
170     while (Size) {
171
172         unsigned I;
173
174         /* Output one line */
175         unsigned Chunk = Size;
176         if (Chunk > BytesPerLine) {
177             Chunk = BytesPerLine;
178         }
179         fputs ("    ", F);
180         for (I = 0; I < Chunk; ++I) {
181             switch (Base) {
182                 case 10:
183                     fprintf (F, "%u,", *D++);
184                     break;
185                 case 16:
186                     fprintf (F, "0x%02X,", *D++);
187                     break;
188
189             }
190         }
191         fputc ('\n', F);
192
193         /* Bump the counters */
194         Size -= Chunk;
195     }
196
197     /* Terminate the array */
198     fputs ("};\n", F);
199
200     /* Close the file */
201     if (fclose (F) != 0) {
202         Error ("Error closing output file `%s': %s", Name, strerror (errno));
203     }
204 }
205
206
207