]> git.saurik.com Git - wxWidgets.git/blob - contrib/utils/convertrc/rc2wxr.cpp
glibc's vswprintf doesn't nul terminate on truncation.
[wxWidgets.git] / contrib / utils / convertrc / rc2wxr.cpp
1 // rc2wxr.cpp: implementation of the rc2wxr class.
2 //
3 //////////////////////////////////////////////////////////////////////
4 //Author: Brian Gavin 9/24/00
5 //License: wxWindows License
6 /*
7 WARNING- I know this code has some bugs to work out but
8 I don't plan to fix them since I feel that wxr files will
9 not be used much longer.
10 This code was used as a starting point for my rc2xml converter
11 */
12
13 // For compilers that support precompilation, includes "wx/wx.h".
14 #include "wx/wxprec.h"
15
16 #ifdef __BORLANDC__
17 #pragma hdrstop
18 #endif
19
20 // for all others, include the necessary headers (this file is usually all you
21
22 // need because it includes almost all "standard" wxWidgets headers
23
24 #ifndef WX_PRECOMP
25 #include "wx/wx.h"
26 #endif
27
28 #include "wx/image.h"
29 #include "wx/deprecated/setup.h"
30 #include "wx/deprecated/resource.h"
31
32 #include "rc2wxr.h"
33
34 //////////////////////////////////////////////////////////////////////
35 // Construction/Destruction
36 //////////////////////////////////////////////////////////////////////
37
38 rc2wxr::rc2wxr()
39 {
40 m_done=false;
41 m_controlid=6000;
42 }
43
44 rc2wxr::~rc2wxr()
45 {
46 }
47
48 void rc2wxr::Convert(wxString wxrfile, wxString rcfile)
49 {
50 m_rc.Open(rcfile);
51 m_filesize=m_rc.Length();
52 if( (m_wxr = wxFopen( wxrfile, _T("wt") )) == NULL )
53 {
54 return;
55 }
56
57 wxString tok,prevtok;
58
59 while (!m_done)
60 {
61 tok=GetToken();
62
63 if (tok==_T("DIALOG"))
64 {
65 ParseDialog(prevtok);
66 }
67
68 if (tok==_T("MENU"))
69 {
70 ParseMenu(prevtok);
71 }
72
73 prevtok=tok;
74 }
75
76 fclose(m_wxr);
77
78 m_rc.Close();
79 }
80
81
82 /*
83
84 Example .rc
85
86 Microsoft style as of v5.0
87
88 IDD_ABOUTBOX DIALOG DISCARDABLE 0, 0, 217, 55
89
90 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
91
92 CAPTION "About Funimator"
93
94 FONT 8, "MS Sans Serif"
95
96 Borland 4.5 style rc
97
98 IDD_DIBATTR DIALOG 7, 16, 172, 119
99
100 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
101
102 CAPTION "DIB Attributes"
103
104 FONT 8, "MS Sans Serif"
105
106 {
107
108 DEFPUSHBUTTON "Ok", IDOK, 114, 8, 50, 14
109
110 PUSHBUTTON "Cancel", IDCANCEL, 114, 28, 50, 14
111
112 */
113
114 void rc2wxr::ParseDialog(wxString dlgname)
115
116 {
117
118 wxString tok;
119
120 static int dlgid=999;
121
122 dlgid++;
123
124 /* Make sure that this really is a dialog
125
126 microsoft reuses the keyword DIALOG for other things
127
128 */
129
130 tok=PeekToken();
131
132 //Microsoft notation?
133
134 if (tok==_T("DISCARDABLE"))
135
136 {
137
138 tok=GetToken();
139
140 tok=PeekToken();
141
142 }
143
144 //This isn't a Dialog resource eject eject
145
146 if (!tok.IsNumber())
147
148 return;
149
150 //Generate Dialog text
151
152 wxFprintf(m_wxr,_T("static char *dialog%i = \"dialog(name = '%s',\\\n"),dlgid,dlgname.c_str());
153
154 //be lazy about style for now. add it later
155
156 wxFprintf(m_wxr,_T("style = 'wxRAISED_BORDER | wxCAPTION | wxRESIZE_BORDER | wxSYSTEM_MENU',\\\n"));
157 wxFprintf(m_wxr,_T("id = %i,\\\n"),dlgid);
158
159 //Record x,y,width,height
160
161 int x,y,width,height;
162
163 ReadRect(x,y,width,height);
164
165 wxFprintf(m_wxr,_T("x = %i, y = %i, width = %i, height = %i,\\\n"),x,y,width,height);
166
167
168 //CAPTION "About Funimator"
169
170 //Get Title
171
172 tok=GetToken();
173
174 wxString title;
175
176
177
178 while ((tok!=_T("BEGIN"))&(tok!=_T("{")))
179
180 {
181
182 if (tok==_T("CAPTION"))
183
184 {
185
186 title=GetQuoteField();
187
188 wxFprintf(m_wxr,_T("title = '%s',\\\n"),title.c_str());
189
190 }
191
192 tok=GetToken();
193
194 }
195
196 wxFprintf(m_wxr,_T("use_dialog_units = 1,\\\n"));
197
198 wxFprintf(m_wxr,_T("use_system_defaults = 0,\\\n"));
199
200
201
202 wxFprintf(m_wxr,_T("font = [8, 'wxSWISS', 'wxNORMAL', 'wxNORMAL', 0, 'MS Sans Serif'],\\\n"));
203
204 ParseControls();
205
206 wxFprintf(m_wxr,_T(").\";\n\n"));
207
208 }
209
210
211
212 /*
213
214 BEGIN
215
216
217
218
219
220
221
222 EDITTEXT IDC_BANDS,36,83,22,14,ES_AUTOHSCROLL | ES_NUMBER | NOT
223
224 WS_TABSTOP
225
226 LTEXT "Bands",IDC_STATIC,11,86,21,8
227
228 EDITTEXT IDC_NAME,10,3,75,14,ES_AUTOHSCROLL
229
230 END
231
232 */
233
234 void rc2wxr::ParseControls()
235
236 {
237
238 wxString tok;
239
240
241
242 tok=GetToken();
243
244 while ((tok!=_T("END"))&(tok!=_T("}")))
245
246 {
247
248 if (tok==_T("LTEXT"))
249
250 ParseStaticText();
251
252 if (tok==_T("EDITTEXT"))
253
254 ParseTextCtrl();
255
256 if (tok==_T("PUSHBUTTON"))
257
258 ParsePushButton();
259
260 if (tok==_T("DEFPUSHBUTTON"))
261
262 ParsePushButton();
263
264 if (tok==_T("GROUPBOX"))
265
266 ParseGroupBox();
267
268 if (tok==_T("COMBOBOX"))
269
270 ParseComboBox();
271
272 if (tok==_T("CONTROL"))
273
274 ParseControlMS();
275
276
277
278 tok=GetToken();
279
280 }
281
282
283
284 }
285
286 //LTEXT "Radius",IDC_STATIC,9,67,23,8
287
288 void rc2wxr::ParseStaticText()
289
290 {
291
292 wxString tok;
293
294 wxString phrase,varname;
295
296 phrase=GetQuoteField();
297
298 varname=GetToken();
299
300 m_controlid++;
301
302 int x,y,width,height;
303
304 ReadRect(x,y,width,height);
305
306 wxFprintf(m_wxr,_T(" control = [%i,wxStaticText,'%s','0','%s',"),m_controlid,phrase.c_str(),varname.c_str());
307
308 wxFprintf(m_wxr,_T("%i,%i,%i,%i,'',\\\n"),x,y,width,height);
309
310 wxFprintf(m_wxr,_T("[8, 'wxSWISS', 'wxNORMAL', 'wxNORMAL', 0, 'MS Sans Serif']],\\\n"));
311
312 }
313
314 //EDITTEXT IDC_RADIUS,36,65,40,14,ES_AUTOHSCROLL
315
316 void rc2wxr::ParseTextCtrl()
317
318 {
319
320 wxString tok;
321
322 wxString varname;
323
324 varname=GetToken();
325
326 m_controlid++;
327
328 int x,y,width,height;
329
330 ReadRect(x,y,width,height);
331
332 wxFprintf(m_wxr,_T(" control = [%i,wxTextCtrl,'','0','%s',"),m_controlid,varname.c_str());
333
334 wxFprintf(m_wxr,_T("%i,%i,%i,%i,'',\\\n"),x,y,width,height);
335
336 wxFprintf(m_wxr,_T("[8, 'wxSWISS', 'wxNORMAL', 'wxNORMAL', 0, 'MS Sans Serif']],\\\n"));
337
338
339
340 }
341
342 //PUSHBUTTON "Create/Update",IDC_CREATE,15,25,53,13,NOT WS_TABSTOP
343
344 void rc2wxr::ParsePushButton()
345
346 {
347
348 wxString tok;
349
350 wxString phrase,varname;
351
352 phrase=GetQuoteField();
353
354 varname=GetToken();
355
356 int c;
357
358 m_controlid++;
359
360 c=m_controlid;
361
362 if (varname==_T("IDOK"))
363
364 c=wxID_OK;
365
366
367
368 if (varname==_T("IDCANCEL"))
369
370 c=wxID_CANCEL;
371
372
373
374 if (varname==_T("IDAPPLY"))
375
376 c=wxID_APPLY;
377
378
379
380 int x,y,width,height;
381
382 ReadRect(x,y,width,height);
383
384 wxFprintf(m_wxr,_T(" control = [%i,wxButton,'%s','0','%s',"),c,phrase.c_str(),varname.c_str());
385
386 wxFprintf(m_wxr,_T("%i,%i,%i,%i,'',\\\n"),x,y,width,height);
387
388 wxFprintf(m_wxr,_T("[8, 'wxSWISS', 'wxNORMAL', 'wxNORMAL', 0, 'MS Sans Serif']],\\\n"));
389
390
391
392 }
393
394
395
396
397
398 bool rc2wxr::Separator(int ch)
399
400 {
401
402 if ((ch==' ')|(ch==',')|(ch==13)|(ch==10)|(ch=='|'))
403
404 return true;
405
406
407
408 if (ch==EOF)
409
410 {
411
412 m_done=true;
413
414 return true;
415
416 }
417
418 return false;
419
420 }
421
422
423
424 void rc2wxr::ParseGroupBox()
425
426 {
427
428 // GROUPBOX "Rotate",IDC_STATIC,1,1,71,79
429
430 wxString tok;
431
432 wxString phrase,varname;
433
434 phrase=GetQuoteField();
435
436 varname=GetToken();
437
438 m_controlid++;
439
440 int x,y,width,height;
441
442 ReadRect(x,y,width,height);
443
444 wxFprintf(m_wxr,_T(" control = [%i,wxStaticBox,'%s','0','%s',"),m_controlid,phrase.c_str(),varname.c_str());
445
446 wxFprintf(m_wxr,_T("%i,%i,%i,%i,'',\\\n"),x,y,width,height);
447
448 wxFprintf(m_wxr,_T("[8, 'wxSWISS', 'wxNORMAL', 'wxNORMAL', 0, 'MS Sans Serif']],\\\n"));
449
450
451
452
453
454 }
455
456
457
458 void rc2wxr::ReadRect(int & x, int & y, int & width, int & height)
459
460 {
461
462 x=wxAtoi(GetToken());
463
464 y=wxAtoi(GetToken());
465
466 width=wxAtoi(GetToken());
467
468 height=wxAtoi(GetToken());
469
470
471
472 }
473
474
475
476 wxString rc2wxr::GetToken()
477
478 {
479
480 wxString tok=wxEmptyString;
481
482
483
484 if (m_rc.Eof())
485
486 {
487
488 m_done=true;
489
490 return tok;
491
492 }
493
494
495
496 int ch=0;
497
498 ReadChar(ch);
499
500 if (ch==EOF)
501
502 {
503
504 m_done=true;
505
506 return tok;
507
508 }
509
510
511
512 while (Separator(ch))
513
514 {
515
516 ReadChar(ch);
517
518 if (m_done)
519
520 return tok;
521
522 }
523
524
525
526 if (ch==EOF)
527
528 {
529
530 m_done=true;
531
532
533
534 }
535
536
537
538
539
540 while (!Separator(ch))
541
542 {
543
544 tok+=(char)ch;
545
546 ReadChar(ch);
547
548
549
550 }
551
552
553
554 if (ch==EOF)
555
556 m_done=true;
557
558
559
560
561
562 return tok;
563
564 }
565
566
567
568 wxString rc2wxr::GetQuoteField()
569 {
570 wxString phrase;
571
572 //ASCII code 34 "
573 int ch=0;
574 ReadChar(ch);
575
576 while (ch!=34)
577 ReadChar(ch);
578
579 ReadChar(ch);
580
581 while (ch!=34)
582 {
583 phrase+=(char)ch;
584 ReadChar(ch);
585 }
586
587 return phrase;
588 }
589
590
591
592 void rc2wxr::ReadChar(int &ch)
593 {
594 wxFileOffset result = m_rc.Tell();
595
596 if ( result >= m_filesize )
597 m_done=true;
598
599 result = m_rc.Read(&ch,1);
600
601 if ( result==wxInvalidOffset )
602 m_done=true;
603
604 if(ch==EOF)
605 m_done=true;
606 }
607
608
609 /* COMBOBOX IDC_SCALECOMBO,10,110,48,52,CBS_DROPDOWNLIST | CBS_SORT |
610 WS_VSCROLL | WS_TABSTOP */
611 void rc2wxr::ParseComboBox()
612 {
613 int x,y,width,height;
614 wxString tok;
615 wxString varname = GetToken();
616
617 m_controlid++;
618
619 ReadRect(x,y,width,height);
620 wxFprintf(m_wxr,_T(" control = [%i,wxChoice,'','0','%s',"),m_controlid,varname.c_str());
621 wxFprintf(m_wxr,_T("%i,%i,%i,%i,[],\\\n"),x,y,width,height);
622 wxFprintf(m_wxr,_T("[8, 'wxSWISS', 'wxNORMAL', 'wxNORMAL', 0, 'MS Sans Serif']],\\\n"));
623 }
624
625
626 void rc2wxr::ParseMenu(wxString name)
627 {
628 wxString tok;
629 static int menuid=0;
630 menuid++;
631 wxFprintf(m_wxr,_T("static char *MenuBar%i = \"menu(name = '%s',\\\n"),menuid,name.c_str());
632 wxFprintf(m_wxr,_T("menu = \\\n"));
633 wxFprintf(m_wxr,_T("[\\\n"));
634
635 while ((tok!=_T("BEGIN"))&(tok!=_T("{")))
636 tok=GetToken();
637
638 while ((tok!=_T("END"))&(tok!=_T("}")))
639 {
640 tok=GetToken();
641
642 if (tok==_T("POPUP"))
643 {
644 ParsePopupMenu();
645 wxFprintf(m_wxr,_T(" ],\\\n"));
646 }
647 }
648
649 wxFprintf(m_wxr,_T("]).\";\n\n"));
650 }
651
652
653 void rc2wxr::ParsePopupMenu()
654 {
655 static int menuitem=99;
656
657 menuitem++;
658
659 wxString tok = GetQuoteField();
660 int spot;
661
662 //Remove /t because it causes problems
663 spot=tok.First(_T("\\t"));
664 tok=tok.Left(spot);
665
666 wxFprintf(m_wxr,_T(" ['%s',%i,'',\\\n"),tok.c_str(),menuitem);
667
668 while ((tok!=_T("BEGIN"))&(tok!=_T("{")))
669 tok=GetToken();
670
671 while ((tok!=_T("END"))&(tok!=_T("}")))
672 {
673 tok=GetToken();
674
675 if (tok==_T("MENUITEM"))
676 {
677 if (PeekToken()==_T("SEPARATOR"))
678 {
679 wxFprintf(m_wxr,_T(" [],\\\n"));
680 }
681 else
682 {
683 tok=GetQuoteField();
684 //Remove /t because it causes problems
685 spot=tok.First(_T("\\t"));
686 tok=tok.Left(spot);
687 menuitem++;
688 wxFprintf(m_wxr,_T(" ['%s',%i,''],\\\n"),tok.c_str(),menuitem);
689 }
690 }
691 }
692 }
693
694
695
696 wxString rc2wxr::PeekToken()
697 {
698 wxFileOffset p = m_rc.Tell();
699 wxString tok = GetToken();
700 m_rc.Seek(p);
701 return tok;
702 }
703
704 //Windows pain in the butt CONTROL
705 void rc2wxr::ParseControlMS()
706 {
707 wxString tok;
708 wxString label=GetQuoteField();
709 wxString varname=GetToken();
710 wxString kindctrl=GetQuoteField();
711
712 kindctrl.MakeUpper();
713 if (kindctrl==_T("MSCTLS_TRACKBAR32"))
714 ParseSlider(label,varname);
715 if (kindctrl==_T("MSCTLS_PROGRESS32"))
716 ParseProgressBar(label,varname);
717 if (kindctrl==_T("BUTTON"))
718 ParseCtrlButton(label,varname);
719 }
720
721 /* CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH |
722 TBS_NOTICKS | WS_TABSTOP,52,73,100,15
723 */
724 void rc2wxr::ParseSlider(wxString WXUNUSED(label), wxString varname)
725 {
726 int x,y,width,height;
727 wxString tok;
728
729 while (ReadOrs(tok))
730 ;
731 wxFprintf(m_wxr,_T(" control = [%i,wxSlider,'','wxSL_HORIZONTAL','%s',"),m_controlid,varname.c_str());
732 ReadRect(x,y,width,height);
733 wxFprintf(m_wxr,_T("%i,%i,%i,%i,"),x,y,width,height);
734 wxFprintf(m_wxr,_T(" 1, 1, 10,\\\n"));
735 wxFprintf(m_wxr,_T("[8, 'wxSWISS', 'wxNORMAL', 'wxNORMAL', 0, 'MS Sans Serif']],\\\n"));
736 }
737
738 /*
739 CONTROL "Progress1",CG_IDC_PROGDLG_PROGRESS,"msctls_progress32",
740 WS_BORDER,15,52,154,13
741 */
742 void rc2wxr::ParseProgressBar(wxString WXUNUSED(label), wxString varname)
743 {
744 int x,y,width,height;
745 wxString tok;
746
747 while (ReadOrs(tok))
748 ;
749
750 wxFprintf(m_wxr,_T(" control = [%i,wxGauge,'','wxGA_HORIZONTAL','%s',"),m_controlid,varname.c_str());
751 ReadRect(x,y,width,height);
752 wxFprintf(m_wxr,_T("%i,%i,%i,%i,"),x,y,width,height);
753 wxFprintf(m_wxr,_T(" 0, 10,\\\n"));
754 wxFprintf(m_wxr,_T("[8, 'wxSWISS', 'wxNORMAL', 'wxNORMAL', 0, 'MS Sans Serif']],\\\n"));
755 }
756
757
758 bool rc2wxr::ReadOrs(wxString & w)
759 {
760 wxString tok = PeekToken();
761 if (tok.IsNumber())
762 return false;
763 w=GetToken();
764 return true;
765 }
766
767
768 //Is it a check button or a radio button
769 void rc2wxr::ParseCtrlButton(wxString label, wxString varname)
770 {
771 int x,y,width,height;
772 wxString tok = GetToken();
773
774 m_controlid++;
775
776 if (tok==_T("BS_AUTOCHECKBOX"))
777 {
778 wxFprintf(m_wxr,_T(" control = [%i,wxCheckBox,'%s','0','%s',"),m_controlid,label.c_str(),varname.c_str());
779 while (ReadOrs(tok))
780 ;
781
782 ReadRect(x,y,width,height);
783 wxFprintf(m_wxr,_T("%i,%i,%i,%i,0,\\\n"),x,y,width,height);
784 wxFprintf(m_wxr,_T("[8, 'wxSWISS', 'wxNORMAL', 'wxNORMAL', 0, 'MS Sans Serif']],\\\n"));
785 }
786
787 if (tok==_T("BS_AUTORADIOBUTTON"))
788 {
789 wxFprintf(m_wxr,_T(" control = [%i,wxRadioButton,'%s','0','%s',"),m_controlid,label.c_str(),varname.c_str());
790 while(ReadOrs(tok))
791 ;
792
793 ReadRect(x,y,width,height);
794 wxFprintf(m_wxr,_T("%i,%i,%i,%i,0,\\\n"),x,y,width,height);
795 wxFprintf(m_wxr,_T("[8, 'wxSWISS', 'wxNORMAL', 'wxNORMAL', 0, 'MS Sans Serif']],\\\n"));
796 }
797 }