1 /*
2  *  This file is part of the XForms library package.
3  *
4  *  XForms is free software; you can redistribute it and/or modify it
5  *  under the terms of the GNU Lesser General Public License as
6  *  published by the Free Software Foundation; either version 2.1, or
7  *  (at your option) any later version.
8  *
9  *  XForms is distributed in the hope that it will be useful, but
10  *  WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  *  Lesser General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Lesser General Public License
15  *  along with XForms.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 
19 /**
20  * \file util.c
21  *
22  *  This file is part of the XForms library package.
23  *  Copyright (c) 1996-2002  T.C. Zhao and Mark Overmars
24  *  All rights reserved.
25  *
26  * X independent utilities
27  */
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32 
33 #include "include/forms.h"
34 #include "flinternal.h"
35 #include <string.h>
36 #include <stdlib.h>
37 #include <sys/types.h>
38 
39 
40 /***************************************
41  * Returns if two objects are the same - not of any use normally,
42  * but seems to help with the Python port (so don't use it for
43  * anything else, it might be gone if it should not needed for
44  * the Python port anymore)
45  ***************************************/
46 
47 int
fl_is_same_object(FL_OBJECT * obj1,FL_OBJECT * obj2)48 fl_is_same_object( FL_OBJECT * obj1,
49                    FL_OBJECT * obj2 )
50 {
51     return obj1 == obj2;
52 }
53 
54 
55 /***************************************
56  * Sets the form window
57  ***************************************/
58 
59 void
fli_set_form_window(FL_FORM * form)60 fli_set_form_window( FL_FORM * form )
61 {
62     if ( form && form->window != None )
63         flx->win = form->window;
64 }
65 
66 
67 /***************************************
68  * Function is kept only for backward compatibility
69  ***************************************/
70 
71 void
fl_show_errors(int y FL_UNUSED_ARG)72 fl_show_errors( int y   FL_UNUSED_ARG )
73 {
74 }
75 
76 
77 /***************************************
78  * Convenience replacement for XFlush()
79  ***************************************/
80 
81 void
fl_XFlush(void)82 fl_XFlush( void )
83 {
84     XFlush( fl_display );
85 }
86 
87 
88 /***************************************
89  * For debugging
90  ***************************************/
91 
92 #define VN( v )  { v, #v }
93 
94 static FLI_VN_PAIR flevent[ ] =
95 {
96     VN( FL_ENTER     ),
97     VN( FL_LEAVE     ),
98     VN( FL_PUSH      ),
99     VN( FL_RELEASE   ),
100     VN( FL_STEP      ),
101     VN( FL_SHORTCUT  ),
102     VN( FL_UPDATE    ),
103     VN( FL_MOTION    ),
104     VN( FL_KEYPRESS  ),
105     VN( FL_DRAW      ),
106     VN( FL_FOCUS     ),
107     VN( FL_UNFOCUS   ),
108     VN( FL_FREEMEM   ),
109     VN( FL_DRAWLABEL ),
110     VN( FL_DBLCLICK  ),
111     VN( FL_OTHER     ),
112     VN( FL_ATTRIB    ),
113     { -1, NULL }
114 };
115 
116 
117 /***************************************
118  ***************************************/
119 
120 const char *
fli_event_name(int ev)121 fli_event_name( int ev )
122 {
123     return fli_get_vn_name( flevent, ev );
124 }
125 
126 
127 static FLI_VN_PAIR flclass[ ] =
128 {
129     VN( FL_BUTTON        ),
130     VN( FL_LIGHTBUTTON   ),
131     VN( FL_ROUNDBUTTON   ),
132     VN( FL_ROUND3DBUTTON ),
133     VN( FL_CHECKBUTTON   ),
134     VN( FL_BITMAPBUTTON  ),
135     VN( FL_PIXMAPBUTTON  ),
136     VN( FL_BITMAP        ),
137     VN( FL_PIXMAP        ),
138     VN( FL_BOX           ),
139     VN( FL_TEXT          ),
140     VN( FL_MENU          ),
141     VN( FL_CHART         ),
142     VN( FL_CHOICE        ),
143     VN( FL_COUNTER       ),
144     VN( FL_SLIDER        ),
145     VN( FL_VALSLIDER     ),
146     VN( FL_INPUT         ),
147     VN( FL_BROWSER       ),
148     VN( FL_DIAL          ),
149     VN( FL_TIMER         ),
150     VN( FL_CLOCK         ),
151     VN( FL_POSITIONER    ),
152     VN( FL_FREE          ),
153     VN( FL_XYPLOT        ),
154     VN( FL_FRAME         ),
155     VN( FL_LABELFRAME    ),
156     VN( FL_CANVAS        ),
157     VN( FL_GLCANVAS      ),
158     VN( FL_TABFOLDER     ),
159     VN( FL_SCROLLBAR     ),
160     VN( FL_SCROLLBUTTON  ),
161     VN( FL_MENUBAR       ),
162     VN( FL_IMAGECANVAS   ),
163     VN( FL_TEXTBOX       ),
164     VN( FL_SPINNER       ),
165     { -1, NULL }
166 };
167 
168 
169 /***************************************
170  ***************************************/
171 
172 const char *
fli_object_class_name(FL_OBJECT * ob)173 fli_object_class_name( FL_OBJECT * ob )
174 {
175     if ( ! ob )
176         return "null";
177     else if ( ob == FL_EVENT )
178         return "FL_EVENT";
179 
180     return fli_get_vn_name( flclass, ob->objclass );
181 }
182 
183 
184 /***************************************
185  * Function tries to read a line (of arbirary length) from a file
186  * On failure (either due to read error or missing memory) NULL is
187  * returned, otherwise a pointer to an allocated buffer that must
188  * be freed by the caller.
189  ***************************************/
190 
191 #define STRING_TRY_LENGTH 128
192 
193 char *
fli_read_line(FILE * fp)194 fli_read_line( FILE *fp )
195 {
196     char *line = NULL;
197     char *old_line = NULL;
198     size_t len = STRING_TRY_LENGTH;
199     size_t old_len = 0;
200 
201     while ( 1 )
202     {
203         if ( ( line = fl_realloc( line, len ) ) == NULL )
204         {
205             fli_safe_free( old_line );
206             M_err( "fli_read_line", "Running out of memory\n" );
207             return NULL;
208         }
209 
210         if ( ! fgets( line + old_len, len - old_len, fp ) )
211         {
212             if ( ferror( fp ) )
213             {
214                 M_err( "fli_read_line", "Failed to read from file" );
215                 fl_free( line );
216                 return NULL;
217             }
218 
219             if ( old_len == 0 )
220             {
221                 fl_free( line );
222                 return NULL;
223             }
224 
225             M_warn( "fli_read_line", "Missing newline at end of line" );
226             break;
227         }
228 
229         if ( strchr( line + old_len, '\n' ) )
230             break;
231 
232         old_line = line;
233         old_len = len - 1;
234         len *= 2;
235     }
236 
237     old_line = line;
238     if ( ( line = fl_realloc( line, strlen( line ) + 1 ) ) == NULL )
239         return old_line;
240     return line;
241 }
242 
243 
244 /*******************************************
245  * Secure string copy: a maximum of (n-1) bytes will be copied, the
246  * destination string is always ends in a '\0'.
247  * Returns: dest or NULL if src or dest are NULL or n is 0
248  *******************************************/
249 
250 char *
fli_sstrcpy(char * dest,const char * src,size_t n)251 fli_sstrcpy( char       * dest,
252              const char * src,
253              size_t       n )
254 {
255     size_t l = src ? strlen( src ) : 0;
256 
257     if ( ! src || ! dest || n == 0 )
258         return NULL;
259 
260     if ( l < n )
261         memcpy( dest, src, l + 1 );
262     else
263     {
264         memcpy( dest, src, n - 1 );
265         dest[ n - 1 ] = '\0';
266     }
267 
268     return dest;
269 }
270 
271 
272 /*
273  * Local variables:
274  * tab-width: 4
275  * indent-tabs-mode: nil
276  * End:
277  */
278