define mv_lastused char(512) define mv_generated_exe integer ################################################################################ function module_menu() define lv_ok integer call clear_screen_portion() call init_filename() MENU "Module" command "Modify" "Modify an existing module" let mv_generated_exe=false call modify_module("",FALSE,"") RETURNING lv_ok if lv_ok then if mv_generated_exe then next option "Run" else next option "Program-Compile" end if end if command "New" "Create a new empty module" let mv_generated_exe=false if new_module() then if mv_generated_exe then next option "Run" end if end if command "Compile" "Compile a module" let mv_generated_exe=false call module_menu_compile() returning lv_ok if lv_ok then if mv_generated_exe then next option "Run" else next option "Program-Compile" end if end if command "Program-Compile" "Compile a program" call program_compile() next option "Run" command "Run" "Run a program" call program_run() { command "Drop" "Delete a module" call drop_module() } command "Exit" "Return to main menu" exit menu end menu end function ################################################################################ function modify_module(lv_mname,lv_errfile,lv_initstate) define lv_mname char(512) define lv_runstr char(512) define lv_backup char(512) define lv_errfile integer define lv_initstate char(30) define lv_need_backup integer define lv_need_to_edit integer define lv_ok integer define lv_state char(30) define lv_next_suggested_state char(30) define lv_editor char(256) define lv_makefile,lv_objfile char(512) let lv_need_to_edit=true let lv_need_backup=false if lv_mname is null or lv_mname matches "" then let lv_mname=get_filename_to("modify",".4gl",mv_lastused) let lv_need_backup=true if lv_mname is null or lv_mname = " " then return false end if end if if lv_mname not matches "*.4[Gg][Ll]" then let lv_mname=lv_mname clipped,".4gl" end if if lv_need_backup and lv_errfile then error "Internal error - not expecting both lv_need_backup and lv_errfile to be set" exit program 99 end if if lv_errfile then # We might be editing the error file # but we still want to backup the original .4gl... let lv_need_backup=true let lv_need_to_edit=false end if if lv_need_backup then # lets make a backup if they've just picked the file... # if we we're passed in a filename - then there should already be # a backup... let lv_backup=aclfgl_replace_in_string(lv_mname,".4gl",".4bl") if file_exists(lv_backup) then error "Could not make backup copy of file (",lv_backup clipped," exists)" return false end if if file_exists(lv_mname) then call copy_file(lv_mname,lv_backup,".4gl",0) end if else initialize lv_backup to null end if if lv_initstate is null or lv_initstate=" " then if lv_need_to_edit then let lv_state="Edit" else let lv_state="CorrectExit" end if else let lv_state=lv_initstate end if while true CALL display_banner() case when lv_state="Edit" message " " CALL ensure_editor() returning lv_editor if lv_editor is null or lv_editor matches " " then error "Unable to get EDITOR" return FALSE end if IF module_editfile(lv_mname,FALSE) THEN # We dont care about the return code... END IF if not file_exists(lv_mname) then LET lv_state="ExitFalse" else LET lv_state="ModifyMenu" LET lv_next_suggested_state="Compile" end if when lv_state="Correct" message " " CALL ensure_editor() returning lv_editor if lv_need_backup =false then # lets make a backup if they've just picked the file... # if we we're passed in a filename - then there should already be # a backup... let lv_backup=aclfgl_replace_in_string(lv_mname,".4gl",".4bl") if file_exists(lv_backup) then error "Could not make backup copy of file (",lv_backup clipped," exists)" return false end if if file_exists(lv_mname) then call copy_file(lv_mname,lv_backup,".4gl",0) end if let lv_need_backup=true end if IF module_editfile(lv_mname,TRUE) THEN if copy_err_file_back_v2(lv_mname,"|") then LET lv_state="ModifyMenu" LET lv_next_suggested_state="Compile" else error "Something horrid happend - I dont want to talk about it.." return false end if ELSE LET lv_state="ModifyMenu" LET lv_next_suggested_state="Compile" END IF when lv_state="ModifyMenu" MENU "Modify Module" BEFORE MENU if lv_next_suggested_state="Save-and-exit" then next option "Save-and-exit" end if if lv_next_suggested_state="Compile" then next option "Compile" end if COMMAND KEY "c" "Compile" "Compile the module" LET lv_state="Compile" EXIT MENU COMMAND KEY "s" "Save-and-exit" "Save the module" LET lv_state="Save-and-exit" message " " EXIT MENU COMMAND KEY "d" "Discard-and-exit" "Discard the module" LET lv_state="Discard-and-exit" message " " EXIT MENU END MENU when lv_state="Save-and-exit" LET lv_state="ExitTrue" when lv_state="Compile" menu "Compile Module" command "Object" "Compile to an object file" let lv_state="CompileObject" exit menu command "Runable" "Compile to an executable" let lv_state="CompileRunable" exit menu command "Exit" "Return to menu" let lv_state="ModifyMenu" let lv_next_suggested_state="Save-and-exit" exit menu end menu when lv_state="CompileObject" let mv_generated_exe=false if fgl_getenv("A4GL_COMPILE_ALONE")="Y" THEN let lv_makefile = " " else call check_program_for_module(lv_mname) returning lv_makefile,lv_objfile end if if lv_makefile = " " or lv_makefile is null then # Couldnt find a real makefile... IF module_compile(lv_mname) then let lv_errfile=false let lv_next_suggested_state="Save-and-exit" if lv_need_backup then let lv_state="ModifyMenu" else let lv_state="ExitTrue" end if ELSE let lv_state="CorrectExit" END IF else display "Compiling as part of program using ", lv_makefile clipped let lv_runstr="make -f ",lv_makefile clipped," ",lv_objfile clipped display "Running : ", lv_runstr clipped call run_with_logging( lv_runstr) returning lv_ok if lv_ok>255 then let lv_ok=lv_ok/256 end if if lv_ok=0 then # Good! let lv_errfile=false let lv_next_suggested_state="Save-and-exit" if lv_need_backup then let lv_state="ModifyMenu" else let lv_state="ExitTrue" end if else if get_use_form() then message "Module did not compile correctly" wait for key else display "Press any key to continue" call fgl_getkey() returning lv_ok end if let lv_state="CorrectExit" end if end if when lv_state="CompileRunable" let mv_generated_exe=false IF module_compile(lv_mname) then let lv_errfile=false let lv_state="ModifyMenu" let lv_runstr="4glc -o ",remove_ext(lv_mname) clipped,".4ae ", remove_ext(lv_mname),fgl_getenv("A4GL_OBJ_EXT") run lv_runstr returning lv_ok if lv_ok>255 then let lv_ok=lv_ok/256 end if if lv_ok=0 then let mv_generated_exe=true if lv_need_backup then let lv_next_suggested_state="Save-and-exit" else let lv_state="ExitTrue" end if else message "Some error creating executable" let lv_next_suggested_state="Save-and-exit" end if ELSE let lv_state="CorrectExit" END IF when lv_state="CorrectExit" MENU "COMPILE FORM" COMMAND KEY "c" "Correct" "Correct the errors in the module" # We need to correct the module.. let lv_state="Correct" exit menu COMMAND KEY "e" "Exit" "Exit the compilation" let lv_state="ExitFalse" exit menu end menu when lv_state="ExitFalse" message " " return FALSE when lv_state="ExitTrue" message " " call remove_file(lv_backup) return TRUE when lv_state="Discard-and-exit" message " " call copy_file(lv_backup,lv_mname,".4gl",0) LET lv_state="ExitTrue" end case END WHILE END FUNCTION function confirm_drop_module() MENU "CONFIRM" BEFORE MENU CALL display_banner() COMMAND KEY "n" "No" "No - I don't want to drop it" RETURN "No" COMMAND KEY "y" "Yes" "Yes - I do want to drop it" RETURN "Yes" END MENU end function FUNCTION module_table_selection() MENU "Generate" BEFORE MENU CALL display_banner() COMMAND KEY "t" "Table selection complete" "Table selection complete" RETURN "Table selection complete" COMMAND KEY "s" "Select more" "Select more" RETURN "Select more" COMMAND KEY "e" "Exit" "Exit" RETURN "Exit" END MENU END FUNCTION ################################################################################ function module_menu_compile() define lv_mname char(512) let lv_mname=get_filename_to("compile",".4gl",mv_lastused) if lv_mname is null or lv_mname matches " " then return false end if let mv_lastused=remove_ext(lv_mname) clipped return modify_module(lv_mname,FALSE, "Compile") end function function module_compile(lv_mname) define lv_mname char(512) define a integer define lv_runstr char(512) if lv_mname not matches "*.4[Gg][Ll]" then let lv_mname=lv_mname clipped,".4gl" end if let lv_runstr=fgl_getenv("AUBITDIR") clipped,"/bin/4glc -c ",lv_mname clipped run lv_runstr returning a if a>255 then let a=a/256 end if if a=0 then message "The module was successfully compiled." return true else message "The module did not compile successfully" return false end if end function ################################################################################ function new_module() define lv_mname char(512) define lv_ok integer let int_flag=false let lv_mname=prompt_get("Module name >>","Enter the module name") if int_flag=true or lv_mname is null or lv_mname matches " " then return false else if lv_mname matches "*.4[Gg][Ll]" then else let lv_mname=lv_mname clipped,".4gl" if file_exists(lv_mname) then error "A module already exists with that name" return false end if end if call modify_module(lv_mname,FALSE,"") returning lv_ok end if return lv_ok end function ################################################################################ function drop_module() define lv_mname char(512) define lv_mname_obj char(512) define lv_mname_4gl char(512) define lv_mname_ec char(512) define lv_mname_c char(512) define a integer #display "Choose a file to drop","" at 2,1 code { char **dir; dir=A4GL_read_directory(".",".4gl"); if (dir) { for (a=0;dir[a];a++) { strcpy(lv_mname,dir[a]); endcode call set_pick(a+1,lv_mname); code } A4GL_free_directory(); } } endcode call set_pick_cnt(a); call set_picked_option(mv_lastused) call prompt_pick_and_say("DROP >> ","","Choose a file to drop") returning lv_mname if lv_mname is not null then let lv_mname_4gl=lv_mname clipped,".4gl" let lv_mname_obj=lv_mname clipped,fgl_getenv("A4GL_OBJ_EXT") if fgl_getenv("A4GL_LEXTYPE")="EC" then let lv_mname_ec=lv_mname clipped,".ec" if fgl_getenv("A4GL_LEXDIALECT")="POSTGRES" then let lv_mname_ec=lv_mname clipped,".cpc" end if else let lv_mname_c=lv_mname clipped,".c" end if let lv_mname_obj=lv_mname clipped,fgl_getenv("A4GL_OBJ_EXT") let lv_mname_obj=lv_mname clipped,fgl_getenv("A4GL_OBJ_EXT") if confirm_drop_module()="Yes" then code A4GL_trim(lv_mname_4gl); A4GL_trim(lv_mname_obj); A4GL_trim(lv_mname_ec); A4GL_trim(lv_mname_c); unlink(lv_mname_4gl); unlink(lv_mname_obj); if (strlen(lv_mname_ec)) unlink(lv_mname_ec); if (strlen(lv_mname_c)) unlink(lv_mname_c); endcode end if end if end function # # Returns True if we need to copy over the errfile # if we dont want to copy back the errfile returns false # eg - if we dont have an errfile - or its missing # function module_editfile(lv_mname,lv_errfile) define lv_mname char(512) define lv_errfile integer define lv_runstr char(512) define a integer define lv_editor char(512) define lv_ename char(512) define lv_copyerrfile integer if lv_errfile then if lv_mname matches "*.4[Gg][Ll]" then let lv_ename=lv_mname[1,length(lv_mname)-3],"err" if file_exists(lv_ename) then let lv_mname=lv_ename let lv_copyerrfile=true else error "Cant see an error file - please manually review any .c.err or .ec.err etc" let lv_errfile=FALSE let lv_copyerrfile=false end if else error "Expecting filename to end with .4gl at this point" exit program 99 end if else let lv_copyerrfile=false let mv_lastused=lv_mname end if let lv_runstr="NOTSET" call ensure_editor() returning lv_editor if lv_errfile then if lv_editor="vi" or lv_editor="vim" or lv_editor="elvis" then let lv_runstr=lv_editor clipped, " +'/^|/' ",lv_mname clipped end if end if if lv_runstr is null or lv_runstr="NOTSET" then let lv_runstr=lv_editor clipped, " ",lv_mname clipped end if run lv_runstr returning a if a>255 then let a=a/256 end if return lv_copyerrfile end function ## # This function checks to see where a module is used # (if at all) # We do this so we can make sure we use the right 'makefile' # or compile from the command line as required ## function check_program_for_module(lv_mname) define lv_mname char(256) define lv_cwd char(256) define lv_cnt integer define lv_prog char(128) define lv_last_used_prog char(128) define lv_have_last_used integer define lv_makefile char(512) define lv_objfile char(512) let lv_cnt=1 # Make sure we dont have any extensions let lv_mname=remove_ext(lv_mname) clipped let lv_cwd=aclfgl_getcwd() let lv_last_used_prog=get_last_used_program() clipped call ensure_syspgma4gl() declare c_chk_prog cursor for select progname from entity where entity_type in ("M","G") and (flags matches " " or flags is null or flags=lv_cwd) and (justuser is null or justuser matches " " or justuser=user) and name=lv_mname order by progname let lv_have_last_used=false foreach c_chk_prog into lv_prog call set_pick(lv_cnt,lv_prog) let lv_cnt=lv_cnt+1 if lv_prog=lv_last_used_prog then let lv_have_last_used=true end if end foreach let lv_cnt=lv_cnt-1 if lv_cnt=0 then # No programs were found - compile from command line return " ", " " end if if lv_cnt=1 then let lv_makefile=get_makefile_for(lv_prog) let lv_objfile=get_object_file_for(lv_prog,lv_mname) return lv_makefile, lv_objfile end if if lv_cnt>1 then if lv_have_last_used then let lv_makefile=get_makefile_for(lv_last_used_prog) let lv_objfile=get_object_file_for(lv_last_used_prog,lv_mname) return lv_makefile, lv_objfile end if end if call set_pick_cnt(lv_cnt) let lv_prog=prompt_pick_and_say("Program >> ","","Pick program for context to compile this module") if lv_prog is not null and lv_prog != " " then call set_last_used_program(lv_prog) let lv_makefile=get_makefile_for(lv_prog) let lv_objfile=get_object_file_for(lv_prog,lv_mname) return lv_makefile, lv_objfile end if # No program select - just compile at command line return " "," " end function function get_object_file_for(lv_prog,lv_mname) define lv_prog char(128) define lv_mname char(256) define lv_builddir char(512) define lv_objext char(10) call ensure_syspgma4gl() select progoutdir into lv_builddir from program where progname=lv_prog and (justuser is null or justuser matches " " or justuser=user) if sqlca.sqlcode=100 then # Its a .mk return (remove_ext(lv_mname) clipped)||fgl_getenv("A4GL_OBJ_EXT") end if let lv_objext= get_setting(lv_prog,"A4GL_OBJ_EXT") clipped if lv_objext is null or lv_objext matches " " then let lv_objext=fgl_getenv("A4GL_OBJ_EXT") clipped end if if lv_builddir is not null and lv_builddir != " " then return lv_builddir clipped|| "/"|| remove_ext(lv_mname) clipped|| lv_objext end if let lv_mname= remove_ext(lv_mname) clipped|| lv_objext return lv_mname end function function get_makefile_for(lv_prog) define lv_prog char(128) define lv_progoutdir, lv_progmakefile char(256) define lv_makefile char(512) define lv_genmakefile integer define lv_lastupd integer define lv_filetime integer call ensure_syspgma4gl() select progoutdir, progmakefile,genmakefile , lastupd into lv_progoutdir, lv_progmakefile,lv_genmakefile,lv_lastupd from program where progname=lv_prog and (justuser is null or justuser matches " " or justuser=user) if sqlca.sqlcode=100 then # Theres nothing in the database # must be a local .mk file... return lv_prog clipped || ".mk" end if if lv_progmakefile is null or lv_progmakefile matches " " then # Theres no *specific* makefile - so we get to choose the name let lv_progmakefile=lv_prog clipped,".mk" end if if lv_lastupd is null then let lv_lastupd=0 end if if lv_genmakefile is null then let lv_genmakefile=0 end if if lv_progmakefile[1]="$" or lv_progmakefile[1]="/" then let lv_makefile=lv_progmakefile else if lv_progoutdir is null or lv_progoutdir matches " " then let lv_makefile="./",lv_progmakefile else let lv_makefile=lv_progoutdir clipped,"/",lv_progmakefile end if end if if file_exists(lv_makefile) then # # Ok - we've got a makefile # # Has the project description changed since the # makefile was last modified ? # let lv_filetime=get_file_time(lv_makefile) if lv_lastupd>lv_filetime then if lv_genmakefile<lv_filetime and lv_genmakefile!=0 then open window w_warn at 10,5 with form "warn" attribute (border,menu line 2) # 1234567890123456789012345678901234567890123456789012345678901234567890 display " Makefile has been changed outside of a4gl IDE (not overwriting) " to warn0 display "lv_lastupd="||lv_lastupd||" lv_filetime="||lv_filetime||" lv_genmakefile="|| lv_genmakefile to warn1 display "The project has been updated since the makefile was last changed." to warn2 display "You can 'touch' the makefile to remove this warning in future " to warn3 menu "Continue" command "Reset" "Ignore the error by using the Makefiles timestamp " update program set (lastupd, genmakefile)=(lv_filetime ,lv_filetime) where progname=lv_prog and (justuser is null or justuser matches " " or justuser=user) exit menu command "Overwrite makefile" "Regenerate the makefile and remove any changes" call generate_makefile(lv_prog,lv_makefile) exit menu command "Ignore Once" "Igore this time only" exit menu end menu close window w_warn else call generate_makefile(lv_prog,lv_makefile) end if #let lv_filetime=get_file_time(lv_makefile) #update program set genmakefile=lv_filetime #where progname=lv_prog #and (justuser is null or justuser matches " " or justuser=user) else # Its already up to date.. end if else # File doesn't exist at all - so generate it. call generate_makefile(lv_prog,lv_makefile) end if return lv_makefile end function