@@ -39,27 +39,27 @@ static int offset;
3939
4040static int offsets [1024 ];
4141
42- /*
43- * exit_window - bool. Control the life of the window.
42+ /* exit_window - bool. Control the life of the window.
4443 * if the value is false, the window remains open;
4544 * otherwise, the window closes.
4645 */
4746static bool exit_window = false;
4847
49- static int init (int argc __attribute__((unused )),
50- char * * argv __attribute__((unused )))
48+ static void free_cmd (cmd_t * cmd );
49+
50+ static bool init (int argc maybe_unused , char * * argv maybe_unused )
5151{
5252 if (SDL_Init (SDL_INIT_VIDEO ) < 0 ) {
5353 printf ("Failed to initialize SDL video. Reason: %s\n" , SDL_GetError ());
54- return 0 ;
54+ return false ;
5555 }
5656
5757 window = SDL_CreateWindow ("Font Editor" , SDL_WINDOWPOS_CENTERED ,
5858 SDL_WINDOWPOS_CENTERED , width , height ,
5959 SDL_WINDOW_SHOWN );
6060 if (!window ) {
6161 printf ("Failed to create SDL window. Reason: %s\n" , SDL_GetError ());
62- return 0 ;
62+ return false ;
6363 }
6464
6565 /* Create an SDL surface linked to the window */
@@ -76,30 +76,65 @@ static int init(int argc __attribute__((unused)),
7676 cairo_scale (cr , scale , scale );
7777
7878 cairo_set_font_size (cr , 2 );
79- return 1 ;
79+ return true;
80+ }
81+
82+ static void cleanup (void )
83+ {
84+ if (cr ) {
85+ cairo_destroy (cr );
86+ cr = NULL ;
87+ }
88+ if (surface ) {
89+ cairo_surface_destroy (surface );
90+ surface = NULL ;
91+ }
92+ if (window ) {
93+ SDL_DestroyWindow (window );
94+ window = NULL ;
95+ }
96+ SDL_Quit ();
8097}
8198
8299static cmd_t * copy_cmd (cmd_t * cmd )
83100{
84- cmd_t * n = malloc (sizeof (cmd_t ));
85101 if (!cmd )
86- return 0 ;
87- * n = * cmd ;
88- n -> next = copy_cmd (cmd -> next );
89- return n ;
102+ return NULL ;
103+
104+ cmd_t * head = NULL ;
105+ cmd_t * * tail = & head ;
106+
107+ while (cmd ) {
108+ cmd_t * n = malloc (sizeof (cmd_t ));
109+ if (!n ) {
110+ /* Cleanup on failure */
111+ free_cmd (head );
112+ return NULL ;
113+ }
114+ * n = * cmd ;
115+ n -> next = NULL ;
116+ * tail = n ;
117+ tail = & n -> next ;
118+ cmd = cmd -> next ;
119+ }
120+
121+ return head ;
90122}
91123
92124static void free_cmd (cmd_t * cmd )
93125{
94- if (cmd ) {
95- free_cmd ( cmd -> next ) ;
126+ while (cmd ) {
127+ cmd_t * next = cmd -> next ;
96128 free (cmd );
129+ cmd = next ;
97130 }
98131}
99132
100133static cmd_t * insert_cmd (cmd_t * * prev )
101134{
102135 cmd_t * n = malloc (sizeof (cmd_t ));
136+ if (!n )
137+ return NULL ;
103138
104139 n -> op = op_noop ;
105140 n -> next = * prev ;
@@ -124,13 +159,21 @@ static void delete_cmd(cmd_t **head, cmd_t *cmd)
124159 free (cmd );
125160}
126161
127- static void push (char_t * c )
162+ static bool push (char_t * c )
128163{
129164 cmd_stack_t * s = malloc (sizeof (cmd_stack_t ));
165+ if (!s )
166+ return false;
130167
131168 s -> cmd = copy_cmd (c -> cmd );
169+ if (!s -> cmd && c -> cmd ) {
170+ free (s );
171+ return false;
172+ }
173+
132174 s -> prev = c -> stack ;
133175 c -> stack = s ;
176+ return true;
134177}
135178
136179static void pop (char_t * c )
@@ -148,7 +191,8 @@ static void pop(char_t *c)
148191
149192static void delete_first_cmd (char_t * c , cmd_t * first )
150193{
151- push (c );
194+ if (!push (c ))
195+ fprintf (stderr , "Warning: cannot save undo state\n" );
152196 delete_cmd (& c -> cmd , first );
153197 c -> first = c -> last = 0 ;
154198}
@@ -171,6 +215,9 @@ static int commas(char *line)
171215static char_t * read_char (FILE * file )
172216{
173217 char_t * c = malloc (sizeof (char_t ));
218+ if (!c )
219+ return NULL ;
220+
174221 char line [1024 ];
175222 cmd_t * cmd ;
176223
@@ -195,16 +242,22 @@ static char_t *read_char(FILE *file)
195242 switch (line [5 ]) {
196243 case 'm' :
197244 cmd = append_cmd (c );
245+ if (!cmd )
246+ goto error ;
198247 cmd -> op = op_move ;
199248 sscanf (line + 8 , "%lf, %lf" , & cmd -> pt [0 ].x , & cmd -> pt [0 ].y );
200249 break ;
201250 case 'l' :
202251 cmd = append_cmd (c );
252+ if (!cmd )
253+ goto error ;
203254 cmd -> op = op_line ;
204255 sscanf (line + 8 , "%lf, %lf" , & cmd -> pt [0 ].x , & cmd -> pt [0 ].y );
205256 break ;
206257 case 'c' :
207258 cmd = append_cmd (c );
259+ if (!cmd )
260+ goto error ;
208261 cmd -> op = op_curve ;
209262 sscanf (line + 8 , "%lf, %lf, %lf, %lf, %lf, %lf" , & cmd -> pt [0 ].x ,
210263 & cmd -> pt [0 ].y , & cmd -> pt [1 ].x , & cmd -> pt [1 ].y , & cmd -> pt [2 ].x ,
@@ -214,7 +267,18 @@ static char_t *read_char(FILE *file)
214267 return c ;
215268 }
216269 }
217- return 0 ;
270+ return NULL ;
271+
272+ error :
273+ free_cmd (c -> cmd );
274+ while (c -> stack ) {
275+ cmd_stack_t * s = c -> stack ;
276+ c -> stack = s -> prev ;
277+ free_cmd (s -> cmd );
278+ free (s );
279+ }
280+ free (c );
281+ return NULL ;
218282}
219283
220284#define DOT_SIZE 1
@@ -408,9 +472,13 @@ static bool is_before(cmd_t *before, cmd_t *after)
408472{
409473 if (!before )
410474 return false;
411- if (before -> next == after )
412- return true;
413- return is_before (before -> next , after );
475+
476+ while (before ) {
477+ if (before -> next == after )
478+ return true;
479+ before = before -> next ;
480+ }
481+ return false;
414482}
415483
416484static void order (cmd_t * * first_p , cmd_t * * last_p )
@@ -425,18 +493,28 @@ static void order(cmd_t **first_p, cmd_t **last_p)
425493static void replace_with_spline (char_t * c , cmd_t * first , cmd_t * last )
426494{
427495 pts_t * pts = new_pts ();
496+ if (!pts ) {
497+ fprintf (stderr , "Error: out of memory\n" );
498+ return ;
499+ }
500+
428501 spline_t s ;
429502 cmd_t * cmd , * next , * save ;
430503
431504 order (& first , & last );
432505 for (cmd = first ; cmd != last -> next ; cmd = cmd -> next ) {
433506 int i = cmd -> op == op_curve ? 2 : 0 ;
434- add_pt (pts , & cmd -> pt [i ]);
507+ if (!add_pt (pts , & cmd -> pt [i ])) {
508+ dispose_pts (pts );
509+ fprintf (stderr , "Error: out of memory\n" );
510+ return ;
511+ }
435512 }
436513
437514 s = fit (pts -> pt , pts -> n );
438515
439- push (c );
516+ if (!push (c ))
517+ fprintf (stderr , "Warning: cannot save undo state\n" );
440518
441519 save = last -> next ;
442520
@@ -446,6 +524,12 @@ static void replace_with_spline(char_t *c, cmd_t *first, cmd_t *last)
446524 }
447525
448526 cmd = insert_cmd (& first -> next );
527+ if (!cmd ) {
528+ pop (c );
529+ dispose_pts (pts );
530+ fprintf (stderr , "Error: out of memory\n" );
531+ return ;
532+ }
449533
450534 cmd -> op = op_curve ;
451535 cmd -> pt [0 ] = s .b ;
@@ -460,13 +544,23 @@ static void split(char_t *c, cmd_t *first, cmd_t *last)
460544{
461545 cmd_t * cmd ;
462546
463- push (c );
547+ if (!push (c ))
548+ fprintf (stderr , "Warning: cannot save undo state\n" );
464549 cmd = insert_cmd (& first -> next );
550+ if (!cmd ) {
551+ pop (c );
552+ fprintf (stderr , "Error: out of memory\n" );
553+ return ;
554+ }
465555 cmd -> op = op_line ;
466556 cmd -> pt [0 ] = lerp (& first -> pt [0 ], & last -> pt [0 ]);
467557 if (last -> op == op_move ) {
468558 cmd_t * extra = insert_cmd (& last -> next );
469-
559+ if (!extra ) {
560+ pop (c );
561+ fprintf (stderr , "Error: out of memory\n" );
562+ return ;
563+ }
470564 extra -> op = op_line ;
471565 extra -> pt [0 ] = last -> pt [0 ];
472566 last -> pt [0 ] = cmd -> pt [0 ];
@@ -482,7 +576,8 @@ static void tweak_spline(char_t *c,
482576{
483577 int i = !!is_2nd_point ;
484578
485- push (c );
579+ if (!push (c ))
580+ fprintf (stderr , "Warning: cannot save undo state\n" );
486581 first -> pt [i ].x += dx ;
487582 first -> pt [i ].y += dy ;
488583}
@@ -658,6 +753,21 @@ static void generate_font_metrics(void)
658753 printf ("\n" );
659754}
660755
756+ static void free_char (char_t * c )
757+ {
758+ if (!c )
759+ return ;
760+
761+ free_cmd (c -> cmd );
762+ while (c -> stack ) {
763+ cmd_stack_t * s = c -> stack ;
764+ c -> stack = s -> prev ;
765+ free_cmd (s -> cmd );
766+ free (s );
767+ }
768+ free (c );
769+ }
770+
661771int main (int argc , char * * argv )
662772{
663773 char_t * c ;
@@ -673,16 +783,22 @@ int main(int argc, char **argv)
673783 return 2 ;
674784 }
675785
676- if (!init (argc , argv ))
677- exit (1 );
786+ if (!init (argc , argv )) {
787+ fclose (file );
788+ return 1 ;
789+ }
790+
678791 while ((c = read_char (file )) && !exit_window ) {
679792 play (c );
680793 print_char (c );
794+ free_char (c );
681795 }
682796
683797 fclose (file );
684798
685799 generate_font_metrics ();
686800
801+ cleanup ();
802+
687803 return 0 ;
688804}
0 commit comments