# Correct the needed linklibs in curl-config also.
[AROS-Contrib.git] / bgui / CAD / cad_main.c
blob0e34474c802234736f76ca67d99ba1138f774160
1 /*
2 * @(#) $Header$
4 * Change AutoDoc program
5 * cad_main.c
7 * (C) Copyright 1998 Manuel Lemos.
8 * (C) Copyright 1996-1997 Ian J. Einman.
9 * (C) Copyright 1993-1996 Jaba Development.
10 * (C) Copyright 1993-1996 Jan van den Baard.
11 * All Rights Reserved.
13 * $Log$
14 * Revision 42.1 2000/05/14 23:32:49 stegerg
15 * changed over 200 function headers which all use register
16 * parameters (oh boy ...), because the simple REG() macro
17 * doesn't work with AROS. And there are still hundreds
18 * of headers left to be fixed :(
20 * Many of these functions would also work with stack
21 * params, but since i have fixed every single one
22 * I encountered up to now, I guess will have to do
23 * the same for the rest.
25 * Revision 42.0 2000/05/09 22:10:54 mlemos
26 * Bumped to revision 42.0 before handing BGUI to AROS team
28 * Revision 41.11 2000/05/09 20:23:16 mlemos
29 * Bumped to revision 41.11
31 * Revision 1.2 2000/05/09 19:55:39 mlemos
32 * Merged with the branch Manuel_Lemos_fixes.
34 * Revision 1.1.2.12 1999/08/29 20:33:28 mlemos
35 * Made the program create a unique temporary file before calling the editor
36 * to allow multiple instances of the program to edit autodoc nodes.
38 * Revision 1.1.2.11 1999/08/21 19:26:21 mlemos
39 * Integrated Anton Rolls changes to fix the command line argument template
40 * handling and XML format support.
42 * Revision 1.1.2.10 1999/05/31 02:52:49 mlemos
43 * Integrated Anton Rolls changes to generate documentation files in
44 * AmigaGuide and HTML formats.
46 * Revision 1.1.2.9 1998/12/26 21:45:18 nobody
47 * Made the program window stay busy while an entry is being edited.
49 * Revision 1.1.2.8 1998/12/26 21:34:29 nobody
50 * Added the ability to set the editor program in the user interface.
52 * Revision 1.1.2.7 1998/12/26 20:57:33 nobody
53 * Added the ability to edit an entry by double clicking on the list.
55 * Revision 1.1.2.6 1998/11/29 22:59:06 mlemos
56 * Made the CAD program return an error code when it can't open BGUI library.
58 * Revision 1.1.2.5 1998/11/28 14:57:43 mlemos
59 * Added BGUI Development Team to the copyright notice.
61 * Revision 1.1.2.4 1998/11/28 14:47:19 mlemos
62 * Undone the changes to set the list view to pre-clear the list entries as
63 * that should have been the list view class default behaviour even for lists
64 * with Display hooks.
66 * Revision 1.1.2.3 1998/11/25 15:34:52 mlemos
67 * Ensured that the list requires pre-clearing because entries are defined by
68 * a custom hook.
69 * Fixed typo in error message when failing to open temporary file.
71 * Revision 1.1.2.2 1998/10/01 04:42:57 mlemos
72 * Added support for the program take input and output file arguments to load
73 * CAD files and generate Autodoc files respectively.
75 * Revision 1.1.2.1 1998/09/19 01:50:19 mlemos
76 * Ian sources.
82 #include "cad.h"
83 #include <stdio.h> /* for printf() */
84 #include <stdlib.h>
86 #define EDITOR_NAME_ENVIRONMENT_VARIABLE "editor"
87 #define DEFAULT_EDITOR_NAME "ed -s"
89 /* see ReadArgs() in main()
90 These are the locations in the array which ReadArgs() fills with nice values for us.
92 #define ARG_FROMLIST 0
93 #define ARG_INPUT 1
94 #define ARG_OUTPUT 2
95 #define ARG_AUTODOC 3
96 #define ARG_AMIGAGUIDE 4
97 #define ARG_HTML 5
98 #define ARG_XML 6
99 #define ARG_VERBOSE 7
100 #define MAX_ARG 8 /* the maximum number of args... keep me up to date! */
102 /* used in ReadArgs() in main() */
103 /* consider putting Output/M */
105 #define ARG_TEMPLATE "FromList/K,From=In=Input,To=Out=Output,Autodoc=Doc/S,Amigaguide=Guide/S,HTML/S,XML/S,Verbose/S"
106 #define EXTENDED_HELP " usages:\n"\
107 "(multiple files, multiple outputs)\n"\
108 " CAD FROMLIST listfile [DOC] [GUIDE] [HTML] [XML]\n\n"\
109 "(single files)\n"\
110 " CAD [IN] file.cad [[TO] file.doc]\n"\
111 " CAD [IN] file.cad [[TO] file.guide]\n"\
112 " CAD [IN] file.cad [[TO] file.html]\n"\
113 " CAD [IN] file.cad [[TO] file.xml]\n"
115 #define BAD_ARG_MESSAGE "The supplied arguments do not match the template.\nType CAD ? for the template, then ? again for extra help.\n"
118 * Global data.
120 UBYTE *VStr = VERSTAG;
121 UBYTE FileName[ 256 ], BaseName[ 64 ], GenName[ 256 ]={0}, GenDir[256]={0};
122 ULONG NumDesc = 0;
125 * Program flags.
127 UBYTE CadChanged = 0;
130 * BGUI objects.
132 Object *WD_Main = NULL;
133 Object *FR_File = NULL;
134 Object *LV_List = NULL;
135 Object *ST_Base = NULL,
136 *ST_Edit = NULL,
137 *ST_Editor = NULL;
138 Object *BT_Add = NULL,
139 *BT_Remove = NULL,
140 *BT_Edit = NULL,
141 *BT_Sort = NULL,
142 *BT_Quit = NULL;
144 struct Library *BGUIBase = NULL;
145 struct Window *MainWindow = NULL;
148 * Object ID's.
150 #define ID_New 1
151 #define ID_Open 2
152 #define ID_Save 3
153 #define ID_Save_As 4
154 #define ID_Generate 5
155 #define ID_About 6
156 #define ID_Quit 7
157 #define ID_Edit 8
158 #define ID_List 9
161 * A simple menu.
163 struct NewMenu Menus[] = {
164 Title( "Project" ),
165 Item( "New", "N", ID_New ),
166 Item( "Open...", "O", ID_Open ),
167 ItemBar,
168 Item( "Save", "S", ID_Save ),
169 Item( "Save As...", "A", ID_Save_As ),
170 ItemBar,
171 Item( "Generate...", "G", ID_Generate ),
172 ItemBar,
173 Item( "About...", "?", ID_About ),
174 ItemBar,
175 Item( "Quit", "Q", ID_Quit ),
179 /*****************
180 ** IDCMP hook. **
181 *****************/
184 * A IDCMP hook for the window which allows us
185 * to control the listview from the keyboard.
187 //STATIC SAVEDS ASM VOID Win_IDCMP_Func( REG(a0) struct Hook *hook, REG(a2) Object *obj, REG(a1) struct IntuiMessage *msg )
188 STATIC SAVEDS ASM REGFUNC3(VOID, Win_IDCMP_Func,
189 REGPARAM(A0, struct Hook *, hook),
190 REGPARAM(A2, Object *, obj),
191 REGPARAM(A1, struct IntuiMessage *, msg))
193 struct Window *window;
194 Object *lv_obj = ( Object * )hook->h_Data;
195 ULONG set = 0;
198 * Obtain window pointer.
200 GetAttr( WINDOW_Window, obj, ( ULONG * )&window );
203 * What key is pressed?
205 switch ( msg->Code ) {
207 case 0x4C:
209 * UP - Move entry up.
210 * SHIFT + UP - Move page up.
211 * CTRL + UP - Move to the top.
213 if ( msg->Qualifier & ( IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT )) set = LISTV_Select_Page_Up;
214 else if ( msg->Qualifier & IEQUALIFIER_CONTROL ) set = LISTV_Select_First;
215 else set = LISTV_Select_Previous;
216 break;
218 case 0x4D:
220 * DOWN - Move entry down.
221 * SHIFT + DOWN - Move page down.
222 * CTRL + DOWN - Move to the end.
224 if ( msg->Qualifier & ( IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT )) set = LISTV_Select_Page_Down;
225 else if ( msg->Qualifier & IEQUALIFIER_CONTROL ) set = LISTV_Select_Last;
226 else set = LISTV_Select_Next;
227 break;
229 case 0x43:
230 case 0x44:
232 * RETURN or ENTER - Report the listview ID to the event handler.
234 DoMethod( obj, WM_REPORT_ID, (( struct Gadget * )lv_obj )->GadgetID, WMRIF_DOUBLE_CLICK );
235 break;
239 * Position changed?
241 if ( set )
242 SetGadgetAttrs(( struct Gadget * )lv_obj, window, NULL, LISTV_Select, set, TAG_END );
245 STATIC struct Hook Win_IDCMP = { NULL, NULL, (HOOKFUNC)Win_IDCMP_Func, NULL, NULL };
247 /*********************
248 ** Listview hooks. **
249 *********************/
251 //STATIC SAVEDS ASM APTR LV_List_Resource_Func( REG(a0) struct Hook *hook, REG(a2) Object *obj, REG(a1) struct lvResource *lvr )
252 STATIC SAVEDS ASM REGFUNC3(APTR, LV_List_Resource_Func,
253 REGPARAM(A0, struct Hook *, hook),
254 REGPARAM(A2, Object *, obj),
255 REGPARAM(A1, struct lvResource *, lvr))
257 APTR rc = NULL;
259 switch ( lvr->lvr_Command ) {
261 case LVRC_MAKE:
263 * We use what is passed in.
265 rc = lvr->lvr_Entry;
266 break;
268 case LVRC_KILL:
269 FreeVec( lvr->lvr_Entry );
270 break;
273 return( rc );
275 //STATIC SAVEDS ASM UBYTE *LV_List_Display_Func( REG(a0) struct Hook *hook, REG(a2) Object *obj, REG(a1) struct lvRender *lvr )
276 STATIC SAVEDS ASM REGFUNC3(UBYTE *, LV_List_Display_Func,
277 REGPARAM(A0, struct Hook *, hook),
278 REGPARAM(A2, Object *, obj),
279 REGPARAM(A1, struct lvRender, *lvr))
282 * Simply return a pointer to the node name
283 * for the Listview class to render.
285 return( &(( CADNODE * )lvr->lvr_Entry )->cn_Name[ 0 ] );
288 //STATIC SAVEDS ASM LONG LV_List_Compare_Func( REG(a0) struct Hook *hook, REG(a2) Object *obj, REG(a1) struct lvCompare *lvc )
289 STATIC SAVEDS ASM REGFUNC3(LONG, LV_List_Compare_Func,
290 REGPARAM(A0, struct Hook *, hook),
291 REGPARAM(A2, Object *, obj),
292 REGPARAM(A1, struct lvCompare *, lvc))
295 * Return the result of stricmp() on the two
296 * node names.
298 return(( LONG )stricmp( &(( CADNODE * )lvc->lvc_EntryA )->cn_Name[ 0 ],
299 &(( CADNODE * )lvc->lvc_EntryB )->cn_Name[ 0 ] ));
302 STATIC struct Hook LV_List_Resource = { NULL, NULL, (HOOKFUNC)LV_List_Resource_Func, NULL, NULL };
303 STATIC struct Hook LV_List_Display = { NULL, NULL, (HOOKFUNC)LV_List_Display_Func, NULL, NULL };
304 STATIC struct Hook LV_List_Compare = { NULL, NULL, (HOOKFUNC)LV_List_Compare_Func, NULL, NULL };
306 /*********************************
307 ** Listview notification hook. **
308 *********************************/
309 //STATIC SAVEDS ASM ULONG LV_List_Func( REG(a0) struct Hook *hook, REG(a2) Object *obj, REG(a1) struct opUpdate *opu )
310 STATIC SAVEDS ASM REGFUNC3(ULONG, LV_List_Func,
311 REGPARAM(A0, struct Hook *, hook),
312 REGPARAM(A2, Object *, obj),
313 REGPARAM(A1, struct opUpdate, *opu))
315 struct TagItem *tag;
316 CADNODE *cn = NULL;
317 UBYTE *contents;
318 ULONG disable;
321 * Let's get the selected node.
323 if ( tag = FindTagItem( LISTV_Entry, opu->opu_AttrList ))
324 cn = ( CADNODE * )tag->ti_Data;
327 * A valid node?
329 if ( cn ) {
330 contents = &cn->cn_Name[ 0 ];
331 disable = FALSE;
332 } else {
333 contents = NULL;
334 disable = TRUE;
338 * Update objects.
340 SetAttr( ST_Edit, opu->opu_GInfo, GA_Disabled, disable, STRINGA_TextVal, contents, TAG_END );
341 MultiSetAttr( opu->opu_GInfo, GA_Disabled, disable, BT_Remove, BT_Edit, NULL );
343 return( 1 );
346 STATIC struct Hook LV_List_Hook = { NULL, NULL, (HOOKFUNC)LV_List_Func, NULL, NULL };
348 /***********************************
349 ** Add button notification hook. **
350 ***********************************/
352 //STATIC SAVEDS ASM BT_Add_Func( REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) struct opUpdate *opu )
353 STATIC SAVEDS ASM REGFUNC3(int, BT_Add_Func,
354 REGPARAM(A0, Class *, cl),
355 REGPARAM(A2, Object *, obj),
356 REGPARAM(A1, struct opUpdate, *opu))
358 CADNODE *cn;
361 * We only respond to final messages.
363 if ( ! ( opu->opu_Flags & OPUF_INTERIM )) {
365 * First we allocate a new node.
367 if ( cn = ( CADNODE * )AllocVec( sizeof( CADNODE ), MEMF_CLEAR )) {
369 * Copy the name "<new>" into it.
371 strcpy( &cn->cn_Name[ 0 ], "<new>" );
374 * Add to the listview.
376 DoMethod( LV_List, LVM_ADDSINGLE, opu->opu_GInfo, cn, LVAP_TAIL, LVASF_SELECT );
378 BGUI_DoGadgetMethod(ST_Edit, MainWindow, NULL, GM_GOACTIVE);
379 ActivateGadget((struct Gadget *)ST_Edit, MainWindow, NULL);
382 * One more entry.
384 NumDesc++;
385 CadChanged = 1;
387 return( 1 );
390 return( 0 );
393 STATIC struct Hook BT_Add_Hook = { NULL, NULL, (HOOKFUNC)BT_Add_Func, NULL, NULL };
395 /**************************************
396 ** Remove button notification hook. **
397 **************************************/
399 //STATIC SAVEDS ASM BT_Remove_Func( REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) struct opUpdate *opu )
400 STATIC SAVEDS ASM REGFUNC3(int, BT_Remove_Func,
401 REGPARAM(A0, Class *, cl),
402 REGPARAM(A2, Object *, obj),
403 REGPARAM(A1, struct opUpdate *, opu))
406 * We only respond to final messages.
408 if (!(opu->opu_Flags & OPUF_INTERIM))
411 * Look up the selected node.
413 if (FirstSelected(LV_List)) {
415 * Remove it from the listview.
417 DoMethod( LV_List, LVM_REMSELECTED, opu->opu_GInfo );
420 * One less...
422 NumDesc--;
423 CadChanged = 1;
425 return 1;
428 return 0;
431 STATIC struct Hook BT_Remove_Hook = { NULL, NULL, (HOOKFUNC)BT_Remove_Func, NULL, NULL };
433 /***********************************
434 ** Edit string notification hook. **
435 ***********************************/
436 //STATIC SAVEDS ASM ST_Edit_Func( REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) struct opUpdate *opu )
437 STATIC SAVEDS ASM REGFUNC3(int, ST_Edit_Func,
438 REGPARAM(A0, Class *, cl),
439 REGPARAM(A2, Object *, obj),
440 REGPARAM(A1, struct opUpdate *, opu))
442 UBYTE *data;
443 CADNODE *cn;
446 * We only respond to final messages.
448 if ( ! ( opu->opu_Flags & OPUF_INTERIM )) {
450 * Look up the selected node.
452 if ( cn = ( CADNODE * )FirstSelected( LV_List )) {
454 * Obtain the new name.
456 GetAttr( STRINGA_TextVal, obj, ( ULONG * )&data );
459 * Did it change?
461 if ( stricmp( data, &cn->cn_Name[ 0 ] )) {
463 * Lock the list.
465 DoMethod( LV_List, LVM_LOCKLIST, NULL );
468 * Copy the name.
470 strcpy( &cn->cn_Name[ 0 ], data );
473 * Unlock the list.
475 DoMethod( LV_List, LVM_UNLOCKLIST, NULL );
478 * Refresh.
480 DoMethod( LV_List, LVM_REDRAW, opu->opu_GInfo );
481 CadChanged = 1;
483 return( 1 );
487 return( 0 );
490 STATIC struct Hook ST_Edit_Hook = { NULL, NULL, (HOOKFUNC)ST_Edit_Func, NULL, NULL };
492 /**************************************
493 ** Sort button notification hook. **
494 **************************************/
496 //STATIC SAVEDS ASM BT_Sort_Func(REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) struct opUpdate *opu)
497 STATIC SAVEDS ASM REGFUNC3(int, BT_Sort_Func,
498 REGPARAM(A0, Class *, cl),
499 REGPARAM(A2, Object *, obj),
500 REGPARAM(A1, struct opUpdate *, opu))
503 * We only respond to final messages.
505 if (!(opu->opu_Flags & OPUF_INTERIM))
508 * Sort the list.
510 DoMethod(LV_List, LVM_SORT, opu->opu_GInfo);
512 return 1;
514 return 0;
516 STATIC struct Hook BT_Sort_Hook = { NULL, NULL, (HOOKFUNC)BT_Sort_Func, NULL, NULL };
518 /*****************************************
519 ** Base name string notification hook. **
520 *****************************************/
521 //STATIC SAVEDS ASM ST_Base_Func( REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) struct opUpdate *opu )
522 STATIC SAVEDS ASM REGFUNC3(int, ST_Base_Func,
523 REGPARAM(A0, Class *, cl),
524 REGPARAM(A2, Object *, obj),
525 REGPARAM(A1, struct opUpdate *, opu))
527 UBYTE *data;
530 * We only respond to final messages.
532 if ( ! ( opu->opu_Flags & OPUF_INTERIM )) {
534 * Obtain the new name and copy
535 * it into the node.
537 GetAttr( STRINGA_TextVal, obj, ( ULONG * )&data );
538 strcpy( BaseName, data );
540 CadChanged = 1;
542 return( 1 );
544 return( 0 );
547 STATIC struct Hook ST_Base_Hook = { NULL, NULL, (HOOKFUNC)ST_Base_Func, NULL, NULL };
550 * Create the main window.
552 BOOL CreateMainWindow( void )
554 ULONG tmp = 0;
555 UBYTE editor_name[256];
557 if(GetVar(EDITOR_NAME_ENVIRONMENT_VARIABLE,editor_name,sizeof(editor_name)-1,GVF_GLOBAL_ONLY|GVF_LOCAL_ONLY)<0)
558 strcpy(editor_name,DEFAULT_EDITOR_NAME);
559 WD_Main = WindowObject,
560 WINDOW_Title, NAME,
561 WINDOW_MenuStrip, Menus,
562 WINDOW_AutoAspect, TRUE,
563 WINDOW_SmartRefresh, TRUE,
564 WINDOW_ScaleWidth, 25,
565 WINDOW_ScaleHeight, 60,
566 WINDOW_IDCMPHook, &Win_IDCMP,
567 WINDOW_IDCMPHookBits, IDCMP_RAWKEY,
568 WINDOW_AutoKeyLabel, TRUE,
569 WINDOW_MasterGroup,
570 VGroupObject, NormalOffset, NormalSpacing,
571 StartMember,
572 VGroupObject,
573 StartMember,
574 VGroupObject, BOffset(4),
575 StartMember,
576 ST_Base = StringObject,
577 LAB_Label, "_Base Name:",
578 STRINGA_MaxChars, 64,
579 STRINGA_TextVal, BaseName,
580 EndObject,
581 EndMember,
582 EndObject, FixMinHeight,
583 EndMember,
584 StartMember,
585 LV_List = ListviewObject,
586 LISTV_ResourceHook, &LV_List_Resource,
587 LISTV_DisplayHook, &LV_List_Display,
588 LISTV_CompareHook, &LV_List_Compare,
589 LISTV_ShowDropSpot, TRUE,
590 PGA_NewLook, TRUE,
591 PGA_Borderless, TRUE,
592 BT_DragObject, TRUE,
593 BT_DropObject, TRUE,
594 GA_ID, ID_List,
595 EndObject,
596 EndMember,
597 StartMember,
598 ST_Edit = StringObject,
599 STRINGA_MaxChars, 32,
600 GA_Disabled, NumDesc ? FALSE : TRUE,
601 EndObject, FixMinHeight,
602 EndMember,
603 StartMember,
604 VGroupObject, TOffset(4),
605 StartMember,
606 ST_Editor = StringObject,
607 LAB_Label, "_Text editor:",
608 STRINGA_MaxChars, 255,
609 STRINGA_TextVal, (ULONG)editor_name,
610 EndObject,
611 EndMember,
612 EndObject, FixMinHeight,
613 EndMember,
614 StartMember,
615 HGroupObject, Spacing(8), TOffset(4),
616 StartMember,
617 BT_Add = ButtonObject,
618 LAB_Label, "_Add",
619 EndObject,
620 EndMember,
621 StartMember,
622 BT_Remove = ButtonObject,
623 LAB_Label, "_Remove",
624 GA_Disabled, NumDesc ? FALSE : TRUE,
625 EndObject,
626 EndMember,
627 StartMember,
628 BT_Edit = ButtonObject,
629 LAB_Label, "_Edit",
630 GA_ID, ID_Edit,
631 GA_Disabled, NumDesc ? FALSE : TRUE,
632 EndObject,
633 EndMember,
634 StartMember,
635 BT_Sort = ButtonObject,
636 LAB_Label, "_Sort",
637 EndObject,
638 EndMember,
639 EndObject, FixMinHeight,
640 EndMember,
641 EndObject,
642 EndMember,
643 EndObject,
644 EndObject;
647 * Object tree OK?
649 if (WD_Main)
652 * Setip IDCMP hook.
654 Win_IDCMP.h_Data = (APTR)LV_List;
657 * And notification.
659 tmp += AddHook( LV_List, &LV_List_Hook );
660 tmp += AddHook( BT_Add, &BT_Add_Hook );
661 tmp += AddHook( BT_Remove, &BT_Remove_Hook );
662 tmp += AddHook( ST_Edit, &ST_Edit_Hook );
663 tmp += AddHook( BT_Sort, &BT_Sort_Hook );
664 tmp += AddHook( ST_Base, &ST_Base_Hook );
666 if (tmp == 6)
667 return TRUE;
669 DisposeObject( WD_Main );
671 return FALSE;
675 * Run the editor to edit the
676 * node data.
678 VOID RunEditor( CADNODE *cn )
680 BPTR file;
681 UBYTE fname[ L_tmpnam ], rstr[ 256 ], *newdata,*editor_name;
682 LONG rc;
685 * Build temporary file name.
687 tmpnam(fname);
690 * Write old contents.
692 if ( file = Open( fname, MODE_NEWFILE )) {
693 if ( cn->cn_DataLength ) {
694 if ( Write( file, cn->cn_Data, cn->cn_DataLength ) != cn->cn_DataLength ) {
695 DosRequest( "OK", ISEQ_C "Error writing temporary file!" );
696 Close( file );
697 return;
700 Close( file );
701 } else {
702 DosRequest( "OK", ISEQ_C "Unable to open the temporary file!" );
703 return;
707 * Build editor command string.
709 sprintf(rstr, "%s %s", GetAttr(STRINGA_TextVal,ST_Editor,(ULONG *)&editor_name) ? editor_name : (UBYTE *)"$editor", fname);
711 WindowBusy(WD_Main);
714 * Run the editor.
716 if ((rc = SystemTags( rstr, SYS_Input, Input(), SYS_Output, Output(), TAG_END )) == 0)
719 * Open the temporary file.
721 if ( file = Open( fname, MODE_OLDFILE )) {
723 * Find out its length.
725 Seek( file, 0, OFFSET_END );
726 rc = Seek( file, 0, OFFSET_BEGINNING );
728 if ( rc > 0 ) {
730 * Allocate memory for read.
732 if ( newdata = ( UBYTE * )AllocVec( rc, MEMF_ANY )) {
734 * Load it.
736 if ( Read( file, newdata, rc ) == rc ) {
738 * Setup new data and deallocate
739 * the old.
741 if ( cn->cn_Data ) FreeVec( cn->cn_Data );
742 cn->cn_Data = newdata;
743 cn->cn_DataLength = rc;
744 } else {
745 DosRequest( "OK", ISEQ_C "Error reading temporary file!" );
746 FreeVec( newdata );
748 } else
749 MyRequest( "OK", ISEQ_C "Out of memory!" );
750 } else if ( rc == -1 )
751 DosRequest( "OK", ISEQ_C "Error seeking temporary file!" );
752 else {
753 if ( cn->cn_Data ) FreeVec( cn->cn_Data );
754 cn->cn_Data = NULL;
755 cn->cn_DataLength = 0;
757 Close( file );
758 } else
759 DosRequest( "OK", ISEQ_C "Unable to open temporary file!" );
760 } else if ( rc == -1 )
761 DosRequest( "OK", ISEQ_C "Error running the editor!" );
762 else
763 DosRequest( "OK", ISEQ_C "Editor returned %ld!", rc );
765 WindowReady(WD_Main);
767 /* Finsihed editing */
768 DeleteFile(fname); /* Delete temporary file. */
769 ActivateWindow(MainWindow); /* ensure we get the focus back from the editor */
770 ScreenToFront(MainWindow->WScreen); /* pop the screen where CAD has its window to the front */
774 * Pop filerequester.
776 BOOL PopRequest( BOOL savemode, UBYTE *buffer )
778 UBYTE *p;
779 BOOL rc = FALSE;
782 * Create requester if not done yet.
784 if (!FR_File)
786 FR_File = FileReqObject,
787 ASLFR_Window, MainWindow,
788 ASLFR_SleepWindow, TRUE,
789 ASLFR_InitialPattern, "#?.cad",
790 EndObject;
794 * Requester available?
796 if (FR_File)
798 SetAttrs(FR_File, ASLFR_InitialFile, FilePart(buffer),
799 ASLFR_InitialDrawer, GenDir,
800 ASLFR_DoSaveMode, savemode,
801 TAG_END);
803 if (!DoRequest(FR_File))
805 GetAttr(FRQ_Path, FR_File, (ULONG *)&p);
806 strcpy(buffer, p);
807 rc = TRUE;
811 return( rc );
815 * Handle events.
817 VOID HandleEvents(void)
819 ULONG signal,last_entry_clicked=-1,last_click_seconds=0,last_click_micros=0;
820 int rc, running = TRUE;
823 * Obtain window signal mask.
825 GetAttr(WINDOW_SigMask, WD_Main, &signal);
827 while (running)
829 Wait(signal);
831 while ((rc = HandleEvent(WD_Main)) != WMHI_NOMORE)
833 switch (rc)
835 case WMHI_CLOSEWINDOW:
836 case ID_Quit:
837 running = FALSE;
838 break;
840 case ID_Edit:
841 RunEditor((CADNODE *)FirstSelected(LV_List));
842 break;
844 case ID_New:
845 SetGadgetAttrs((struct Gadget *)ST_Base, MainWindow, NULL, STRINGA_TextVal, NULL, TAG_END);
846 ClearList(MainWindow, LV_List);
847 *FileName = *BaseName = *GenName = 0;
848 NumDesc = 0;
849 break;
851 case ID_Open:
852 if (PopRequest(FALSE, FileName))
853 LoadCadFile(1);
854 break;
856 case ID_Save:
857 if (NumDesc)
859 if (FileName[0])
861 SaveCadFile(1);
862 break;
865 /* fall through if no filename. */
867 case ID_Save_As:
868 if (NumDesc)
870 sprintf(FileName, "%s.cad", BaseName);
871 if (PopRequest( TRUE, FileName ))
872 SaveCadFile(1);
873 } else
874 MyRequest("OK", ISEQ_C "Nothing to save!");
875 break;
877 case ID_Generate:
878 if (NumDesc)
880 switch (MyRequest( "*_AutoDoc|_HTML|Amiga_Guide|_Cancel", "Select the output format:" ))
882 case 0: /* cancel - don't do nothin' */
883 break;
885 case 1: /* text */
886 sprintf(GenName, "%s.doc", BaseName);
887 if (PopRequest(TRUE, GenName))
888 Generate(1, MATCH_DOC);
889 break;
891 case 2: /* html */
892 sprintf(GenName, "%s.html", BaseName);
893 if (PopRequest(TRUE, GenName))
894 Generate(1, MATCH_HTML);
895 break;
897 case 3: /* amigaguide */
898 sprintf(GenName, "%s.guide", BaseName);
899 if (PopRequest(TRUE, GenName))
900 Generate(1, MATCH_GUIDE);
901 break;
904 } else
905 MyRequest("OK", ISEQ_C "Nothing to generate!");
906 break;
908 case ID_About:
909 MyRequest( "_Continue", ISEQ_C ISEQ_B NAME " " VERSION " " __AMIGADATE__ "\n\n"
910 ISEQ_N "Copyright © 1998 BGUI Development Team.\n"
911 ISEQ_N "Copyright © 1996 Ian J. Einman.\n"
912 ISEQ_N "Copyright © 1996 Jaba Development." );
913 break;
914 case ID_List:
916 ULONG last_clicked;
918 if(GetAttr(LISTV_LastClickedNum, LV_List, &last_clicked))
920 ULONG seconds,micros;
922 CurrentTime(&seconds,&micros);
923 if(last_entry_clicked==last_clicked
924 && DoubleClick(last_click_seconds,last_click_micros,seconds,micros))
925 RunEditor((CADNODE *)FirstSelected(LV_List));
926 last_click_seconds=seconds;
927 last_click_micros=micros;
928 last_entry_clicked=last_clicked;
936 char *matchlist[] =
937 { "", "fromlist", "to", "doc", "guide", "html", "xml" };
939 /* match a string in the list - return one of the defined MATCH_xxx, or 0 if not found
940 MATCH_xxx defines are in cad.h
943 ULONG Match(const char *string)
945 ULONG i=0;
946 while( i < MATCH_MAX )
948 if( stricmp(string, matchlist[i]) )
949 i++;
950 else
951 break;
954 if( i < MATCH_MAX )
955 return (i);
956 else
957 return (0);
962 These two variables are accessed by main() and ReadAListFile
966 BOOL openMainWindow=TRUE; /* Will we open the main window? */
967 /* This will be set to false when any arguments other than */
968 /* INPUT or VERBOSE are specified, */
969 /* or when there is an error opening a file. */
970 int rc=0; /* main() return code */
971 LONG error=0;
972 BOOL generatedOK=TRUE;
975 * Main entry...
977 int main(LONG argc, char *argv[])
979 void ReadAListFile(LONG *arg);
980 void SingleFile(LONG *arg);
982 struct RDArgs *arguments; /* "handle" necessary for FreeArgs() */
983 LONG arg[MAX_ARG]={0}; /* where the arguments will go finally. */
985 struct RDArgs rdargs = {0}; /* see dos/rdargs.h */
986 rdargs.RDA_ExtHelp = EXTENDED_HELP; /* set the extended help */
988 arguments = ReadArgs(ARG_TEMPLATE, arg, &rdargs);
990 if(!arguments)
992 printf(BAD_ARG_MESSAGE);
993 exit(20);
997 * Open the bgui.library
999 if (BGUIBase = OpenLibrary("bgui.library", 40))
1001 if (CreateMainWindow()) /* Create the main window object tree. */
1003 /* See if user wants to open the window. */
1004 /* This becomes false when there are command line arguments other than */
1005 /* VERBOSE or INPUT are specified. */
1006 /* ie. The user tries to use the command line to generate a file directly, */
1007 /* without using the window, so we don't annoy him by popping it open on any */
1008 /* sort of error */
1010 if( arg[ARG_FROMLIST] ||
1011 arg[ARG_OUTPUT] ||
1012 arg[ARG_AUTODOC] ||
1013 arg[ARG_AMIGAGUIDE] ||
1014 arg[ARG_HTML] ||
1015 arg[ARG_XML]
1018 /* if(arg[ARG_VERBOSE]) printf("!openMainWindow\n"); */
1019 openMainWindow = FALSE;
1022 /* Handle multiple file input - specified with FROMLIST */
1024 if( arg[ARG_FROMLIST] ) /* was FromList specified? */
1026 /* read-a-list-file mode - multiple inputs, multiple outputs */
1027 ReadAListFile(arg);
1030 /* Handle single file input - specified with IN and OUT */
1032 if( arg[ARG_INPUT] ) /* was an input file specified? */
1034 SingleFile(arg); /* single file mode */
1038 if(openMainWindow) /* ==TRUE if the user specifies incomplete or missing arguments */
1040 if (MainWindow = WindowOpen(WD_Main)) /* Open the main window */
1042 HandleEvents();
1046 * Dump the objects.
1048 if (WD_Main) DisposeObject(WD_Main);
1049 if (FR_File) DisposeObject(FR_File);
1052 * Close the bgui.library.
1054 CloseLibrary(BGUIBase);
1056 else /* couldn't open bgui.library v 40 */
1058 rc=20;
1061 if( !generatedOK )
1063 rc=20;
1064 error=IoErr();
1067 SetIoErr(error);
1068 exit(rc);
1070 return (0);
1075 Do all the work that read-a-list-file mode entails:
1076 - open the file specified with FROMLIST
1077 - get filenames out of it one by one, and
1078 - generate the output files, depending on the switches: DOC, HTML, GUIDE etc.
1080 - main() and ReadAListFile both have access to the variables:
1081 openMainWindow, rc, error, and generatedOK
1082 - openMainWindow may be set to FALSE when there is an error opening a file.
1083 - rc may be set to 20 if there is an error opening a file, and
1084 - error records the result of IoErr() in such a case.
1085 - generatedOK is the BOOL result from Generate()
1088 void ReadAListFile(LONG *arg)
1090 void MakeSureFileNameIsOK(UBYTE *);
1092 BPTR listFile;
1093 UBYTE listFileName[256]={0};
1094 char *lastdot; /* to point to the last '.' in a filename */
1096 if( arg[ARG_VERBOSE] ) printf("CAD FROMLIST");
1098 /* try to open the list file and read the filenames to process */
1100 strcpy( listFileName, (char *)arg[ARG_FROMLIST]); /* get listFileName */
1101 if( arg[ARG_VERBOSE] ) printf(" %s", listFileName);
1102 if ( listFile = Open( listFileName, MODE_OLDFILE )) /* Open listFile */
1104 if( arg[ARG_VERBOSE] ) printf(" TO");
1106 /* loop to process successive FileNames from the listFile */
1107 while( FGets(listFile, FileName, 256) ) /* read next line into FileName */
1109 MakeSureFileNameIsOK( FileName);
1111 if( LoadCadFile(0) ) /* load the input file (opens FileName) */
1113 strcpy( GenName, FileName ); /* copy the input file name to output file name */
1115 lastdot = strrchr(GenName, '.'); /* find the last dot in the filename */
1116 if( !lastdot) /* no dot? */
1118 strcat( GenName, "."); /* append a dot to the filename */
1119 lastdot = strrchr(GenName, '.'); /* find the last dot again */
1122 /* good - now find out what types of output we want. */
1123 /* Generate each specified type, modifying GenName so */
1124 /* its extension matches its type. */
1126 if( arg[ARG_AUTODOC] )
1128 strcpy(lastdot+1, "doc" ); /* append "doc" to filename */
1129 generatedOK = Generate(0, MATCH_DOC );
1130 if( arg[ARG_VERBOSE] ) printf("\n %s", GenName);
1133 if( arg[ARG_AMIGAGUIDE] )
1135 strcpy(lastdot+1, "guide" ); /* append "guide" to filename */
1136 generatedOK = Generate(0, MATCH_GUIDE );
1137 if( arg[ARG_VERBOSE] ) printf("\n %s", GenName);
1140 if( arg[ARG_HTML] )
1142 strcpy(lastdot+1, "html" ); /* append "html" to filename */
1143 generatedOK = Generate(0, MATCH_HTML );
1144 if( arg[ARG_VERBOSE] ) printf("\n %s", GenName);
1147 if( arg[ARG_XML] )
1149 strcpy(lastdot+1, "xml" ); /* append "xml" to filename */
1150 generatedOK = Generate(0, MATCH_XML );
1151 if( arg[ARG_VERBOSE] ) printf("\n %s", GenName);
1154 else /* couldn't open the input file - open should be FALSE */
1156 if( arg[ARG_VERBOSE] ) printf(" [couldn't open %s]", FileName);
1157 openMainWindow = FALSE;
1158 rc=20;
1159 error=IoErr();
1161 } /* end of the loop processing the listfile */
1163 Close(listFile);
1165 else /* unable to open listfile */
1167 if( arg[ARG_VERBOSE] ) printf(" [unable to open]");
1168 openMainWindow = FALSE;
1169 rc=20;
1170 error=IoErr();
1172 if( arg[ARG_VERBOSE] ) printf("\n"); /* newline */
1176 After the filename has been read from the FromList file,
1177 its last character could be null or newline (or something
1178 else). It should have a null in order to be a nice c string,
1179 so we make sure it has one.
1182 void MakeSureFileNameIsOK(UBYTE *filename)
1184 UBYTE *lastchar; /* the last character in the filename string */
1186 if(strlen(filename)>0)
1188 lastchar = &filename[ strlen(filename)-1 ];
1190 switch( *(lastchar) )
1192 case '\n': /* if last char is a newline */
1193 *(lastchar) = '\0'; /* replace it with a terminating null */
1194 /* printf("\n %s [last char newline]", filename); */
1195 break;
1197 case '\0': /* if last char is a null - good */
1198 /* printf("\n %s [last char null]", filename); */
1199 break;
1201 default: /* something else ?! - weird */
1202 /* printf("\n %s [last char = %ld not newline or null ]", filename, (LONG) *(lastchar) ); */
1203 break;
1205 /* printf("\n %s", filename); */
1209 void SingleFile(LONG *arg)
1211 /* single-file mode - single input */
1213 char *lastdot; /* to point to the last '.' in a filename */
1215 if( arg[ARG_VERBOSE] ) printf(" [single file mode]");
1217 strcpy( FileName, (char *)arg[ARG_INPUT] ); /* copy the input file name */
1218 if( LoadCadFile(0) ) /* load the input file */
1220 /* input file opened - good */
1221 if( arg[ARG_VERBOSE] ) printf(" %s", FileName);
1223 /* now see if there is an output file */
1224 if( arg[ARG_OUTPUT] )
1226 BOOL foundUsefulExtension = FALSE;
1227 /* take it as the output filename */
1228 /* see what kind of file to create by looking at filename extension */
1230 strcpy( GenName, (char *)arg[ARG_OUTPUT] );
1231 if( arg[ARG_VERBOSE] ) printf(" %s", GenName);
1233 if(lastdot = strrchr(GenName, '.') ) /* find the last dot */
1235 if( strlen(GenName) > lastdot-GenName+1 ) /* chars after last dot ? */
1237 if( Match(lastdot+1) ) /* see if we know the extension */
1239 foundUsefulExtension = TRUE;
1240 generatedOK = Generate(0, Match(lastdot+1) );
1245 if(!foundUsefulExtension) /* we did not find a recognized extension */
1247 /* default to autodoc text file */
1248 generatedOK = Generate(0, MATCH_DOC); /* produce text file */
1251 else /* no output file specified */
1253 /* Here we should check if DOC, GUIDE, HTML or XML tags were specified.
1254 If so, copy the input filename to the output filename, replace the
1255 extension with doc, guide etc, and Generate.
1258 ULONG pathLength=0;
1260 if( arg[ARG_VERBOSE] ) printf(" [no output]");
1261 /* copy the Path part from the input file name to GenDir,
1262 so by default, the generate file requester will show the
1263 same path as specified for the input file. = more friendly
1265 pathLength = (ULONG)( PathPart(FileName) - FileName );
1266 strncat(GenDir, FileName, pathLength);
1269 else /* couldn't open the input file */
1271 if( arg[ARG_VERBOSE] ) printf(" [couldn't open %s]", FileName);
1272 openMainWindow = FALSE; /* Don't open the GUI */
1273 rc=20;
1274 error=IoErr();
1276 if( arg[ARG_VERBOSE] ) printf("\n");