/* File: clm.c Written by: John van Groningen At: University of Nijmegen */ #define CLM_VERSION "2.1" #define VERSION 919 #define OPTIMISE_LINK #if defined (MAKE_MPW_TOOL) && defined (NB) # define NO_CLEAN_SYSTEM_FILES_FOLDERS #endif #define for_l(v,l,n) for(v=(l);v!=NULL;v=v->n) #ifdef OS2 # define OMF # define NO_CLIB #endif #if defined (_WINDOWS_) # undef USE_WLINK # define USE_CLEANLINKER # define NO_CLIB #endif #if defined (_WINDOWS_) || defined (OMF) || defined (LINUX) || defined (SOLARIS) # define NO_ASSEMBLE #endif #ifndef SOLARIS # define MARKING_GC #endif #include #include #include #include #if defined(I486) || defined (SOLARIS) || defined (LINUX) # include #endif #include #if defined (applec) || defined (__MWERKS__) # define MACINTOSH 1 # if __MWERKS__ # define POWER # endif #else # define MACINTOSH 0 #endif #if MACINTOSH # include # include # ifdef applec # include # endif # define USE_PATH_CACHE 1 #else # if !(defined (_WINDOWS_) || defined (OS2)) # include # include # include # endif # ifdef OS2 # include # endif # include # define USE_PATH_CACHE 0 #endif #if USE_PATH_CACHE # include "path_cache.h" #endif #ifdef _WINDOWS_ # ifdef __MWERKS__ # include # else # ifndef GNU_C # define _X86_ # endif # include # endif # ifdef GNU_C # include # else # include # include # endif # include #endif #ifdef OS2 # define INCL_ERRORS # define INCL_DOSFILEMGR # define INCL_DOSPROCESS # include #endif #if !MACINTOSH extern char *getenv(); #endif #define PATH_NAME_STRING_SIZE 256 #define PATH_LIST_STRING_SIZE 1024 /* file and directory names which may be patched using patchbin */ #if defined (I486) && !defined (LINUX) # ifdef OS2 char clean_lib_directory[PATH_NAME_STRING_SIZE] = "\\clean\\lib"; char gcc_lib_directory[PATH_NAME_STRING_SIZE] = "\\emx\\lib"; char assembler_file_name[PATH_NAME_STRING_SIZE] = "as.exe"; # ifdef OMF char linker_file_name[PATH_NAME_STRING_SIZE] = "link386.exe"; char crt0_file_name [PATH_NAME_STRING_SIZE] = "crt0.obj"; # else char gcc_lib_directory_arg[PATH_NAME_STRING_SIZE+2]; char linker_file_name[PATH_NAME_STRING_SIZE] = "ld.exe"; char crt0_file_name [PATH_NAME_STRING_SIZE] = "crt0.o"; # endif # else # ifdef _WINDOWS_ char clean_lib_directory[PATH_NAME_STRING_SIZE] = "d:\\john"; char assembler_file_name[PATH_NAME_STRING_SIZE] = "as.exe"; # ifndef USE_WLINK # ifdef USE_CLEANLINKER char linker_file_name[PATH_NAME_STRING_SIZE] = "linker.exe"; # else char linker_file_name[PATH_NAME_STRING_SIZE] = "ld.exe"; # endif char crt0_file_name [PATH_NAME_STRING_SIZE] = "c:\\gnu\\lib\\crt0.o"; # else char linker_file_name[PATH_NAME_STRING_SIZE] = "wlink"; char crt0_file_name [PATH_NAME_STRING_SIZE] = "crt0.o"; # endif # else char clean_lib_directory[PATH_NAME_STRING_SIZE] = "/usr/scratch/johnvg/clean"; char assembler_file_name[PATH_NAME_STRING_SIZE] = "/usr/bin/as"; char linker_file_name[PATH_NAME_STRING_SIZE] = "/usr/bin/ld"; char crt0_file_name [PATH_NAME_STRING_SIZE] = "/usr/lib/crt0.o"; # endif # endif #else # if defined (SOLARIS) || defined (LINUX) char _clean_lib_directory[PATH_NAME_STRING_SIZE] = "#$@CLEANLIB %*&."; char _clean_directory_list[PATH_LIST_STRING_SIZE]= "#$@CLEANPATH %*&."; # ifdef SOLARIS char _assembler_file_name[PATH_NAME_STRING_SIZE] = "#$@ASSEMBLER %*&/usr/ccs/bin/as"; char _linker_file_name[PATH_NAME_STRING_SIZE] = "#$@LINKER %*&/usr/ccs/bin/ld"; # else char _assembler_file_name[PATH_NAME_STRING_SIZE] = "#$@ASSEMBLER %*&/usr/bin/as"; char _linker_file_name[PATH_NAME_STRING_SIZE] = "#$@LINKER %*&/usr/bin/gcc"; # endif char _crt0_file_name [PATH_NAME_STRING_SIZE] = "#$@CRT %*&crt1.o"; char _ld_args [PATH_LIST_STRING_SIZE] = "#$@LDARGS %*&"; /* char _ld_args [PATH_LIST_STRING_SIZE] = "#$@LDARGS %*& --dynamic /lib/ld-linux.so.1"; */ # define clean_lib_directory (&_clean_lib_directory[16]) # define clean_directory_list (&_clean_directory_list[16]) # define assembler_file_name (&_assembler_file_name[16]) # define linker_file_name (&_linker_file_name[16]) # define crt0_file_name (&_crt0_file_name[16]) # define ld_args (&_ld_args[16]) # else char clean_lib_directory[PATH_NAME_STRING_SIZE] = "."; char assembler_file_name[PATH_NAME_STRING_SIZE] = "/bin/as"; char linker_file_name[PATH_NAME_STRING_SIZE] = "/bin/ld"; char crt0_file_name [PATH_NAME_STRING_SIZE] = "/lib/crt0.o"; # endif #endif #ifdef M68000 char Mcrt1_file_name [PATH_NAME_STRING_SIZE] = "/lib/Mcrt1.o"; #endif /* default options of cocl */ #define DEFAULT_WARNING 1 #define DEFAULT_INLINE 1 #define DEFAULT_VERBOSE 0 #define DEFAULT_DEBUG 0 #define DEFAULT_TYPE_CHECK 1 #define DEFAULT_STRICTNESS_ANALYSIS 1 #define DEFAULT_LIST_TYPES 0 #define DEFAULT_LIST_ALL_TYPES 0 #define DEBUG_MASK 1 #define INLINE_MASK 2 #define PARALLEL_MASK 4 #define STACK_LAYOUT_MASK 8 #define STRICTNESS_ANALYSIS_MASK 16 #define TYPE_CHECK_MASK 32 #define VERBOSE_MASK 64 #define WARNING_MASK 128 #define SYSTEM_MASK 256 #define LIST_TYPES_MASK 512 #define LIST_ALL_TYPES_MASK 1024 #define REUSE_UNIQUE_NODES 2048 #define TIME_PROFILE 4096 #define MEMORY_PROFILE 8192 #define DEFAULT_OPTIONS \ (DEFAULT_WARNING ? WARNING_MASK : 0)\ | (DEFAULT_INLINE ? INLINE_MASK : 0)\ | (DEFAULT_VERBOSE ? VERBOSE_MASK : 0)\ | (DEFAULT_DEBUG ? DEBUG_MASK : 0)\ | (DEFAULT_TYPE_CHECK ? TYPE_CHECK_MASK : 0)\ | (DEFAULT_STRICTNESS_ANALYSIS ? STRICTNESS_ANALYSIS_MASK : 0)\ | (DEFAULT_LIST_TYPES ? LIST_TYPES_MASK : 0)\ | (DEFAULT_LIST_ALL_TYPES ? LIST_ALL_TYPES_MASK : 0) static int clean_options=DEFAULT_OPTIONS; static int clean_options_mask=0; static int remove_symbol_table; static int list_strict_export_types=0,funcmayfail_error=0,varnotused_error=0,funcnotused_error=0, nowarn=0,progress=0; static char *cocl_redirect_stdout,*cocl_redirect_stdout_option; static char *cocl_redirect_stderr,*cocl_redirect_stderr_option; static int check_stack_overflow,check_indices; #if defined (MAKE_MPW_TOOL) && defined (NB) static int generate_mc68020_code=0,show_help=0; #endif #ifdef OS2 static int window_application; #endif #ifdef _WINDOWS_ typedef FILETIME FileTime; # define FILE_TIME_LE(t1,t2) ((unsigned)(t1.dwHighDateTime)<(unsigned)(t2.dwHighDateTime) \ || (t1.dwHighDateTime==t2.dwHighDateTime && (unsigned)(t1.dwLowDateTime)<=(unsigned)(t2.dwLowDateTime))) #else typedef unsigned long FileTime; # define FILE_TIME_LE(t1,t2) (t1<=t2) #endif typedef struct project_node { struct project_node * pro_next; char * pro_fname; struct dep_list * pro_depend; int pro_options; FileTime pro_abc_time; FileTime pro_dcl_time; unsigned int pro_up_to_date:1, pro_valid_abc_time:1, pro_valid_dcl_time:1, pro_no_abc_file:1, pro_no_dcl_file:1, pro_valid_options:1, pro_ignore_o:1; } *P_NODE; typedef struct dep_list { struct dep_list * dep_next; P_NODE dep_node; } *DEP_LIST; P_NODE first_project_node,last_project_node,main_project_node; struct library_list { struct library_list * library_next; #if !defined (GNU_C) char library_file_name[]; #else char library_file_name[1]; #endif }; static struct library_list *first_library,*last_library; static void warning_s (char *warning_string,char *s) { fprintf (stderr,warning_string,s); fputc ('\n',stderr); } static void warning_s_s (char *warning_string,char *s1,char *s2) { fprintf (stderr,warning_string,s1,s2); fputc ('\n',stderr); } static void error (char *error_string) { fprintf (stderr,"%s\n",error_string); exit (1); } static void error_s (char *error_string,char *s) { fprintf (stderr,error_string,s); fputc ('\n',stderr); exit (1); } static void *memory_allocate (int size) { void *block; block=malloc (size); if (block==NULL) error ("Out of memory"); return block; } #if defined (OS2) || defined (_WINDOWS_) int dos_exec (char *file_name,char **args,int use_temp_file) { # ifdef OS2 char command[8192]; # else char command[1024]; # endif if (!use_temp_file){ int length; strcpy (command,file_name); strcat (command," "); ++args; while (*args){ strcat (command,*args); strcat (command," "); ++args; } length=strlen (command); command[--length]='\0'; return system (command); } else { char *temp_file_name; FILE *temp_file; int r; #if defined (_WINDOWS_) || defined (OS2) temp_file_name="param.$$$"; # ifdef OMF { char *p; for (p=temp_file_name; *p; ++p) if (*p=='/') *p='\\'; } # endif temp_file=fopen (temp_file_name,"w"); #else { static char param_tmp_file_name[]="/tmp/paramXXXXXX"; int temp_file_fd; temp_file_fd=mkstemp (param_tmp_file_name); if (temp_file_fd<0) return 1; temp_file_name=param_tmp_file_name; temp_file=fdopen (temp_file_fd,"w"); } # endif if (temp_file==NULL) return 1; ++args; while (*args!=NULL){ #ifdef OMF if (*args!=NULL && **args==','){ ++args; fprintf (temp_file,"\n"); } else { if (args[1]!=NULL && *args[1]=='/') fprintf (temp_file,"%s ",*args); else if (args[1]!=NULL && *args[1]!=',') fprintf (temp_file," %s +\n",*args); else fprintf (temp_file,"%s\n",*args); ++args; if (*args!=NULL && **args==',') ++args; } #else fprintf (temp_file,"%s\n",*args); ++args; #endif } if (fclose (temp_file)!=0){ return 1; } sprintf (command,"%s @%s",file_name,temp_file_name); r=system (command); unlink (temp_file_name); return r; } } #endif static P_NODE add_project_node (char *module_name) { P_NODE new_project_node; char *pro_fname; new_project_node=memory_allocate (sizeof (struct project_node)); new_project_node->pro_next=NULL; pro_fname=memory_allocate (1+strlen (module_name)); strcpy (pro_fname,module_name); new_project_node->pro_fname=pro_fname; new_project_node->pro_depend=NULL; new_project_node->pro_up_to_date=0; new_project_node->pro_valid_abc_time=0; new_project_node->pro_valid_dcl_time=0; new_project_node->pro_no_abc_file=0; new_project_node->pro_no_dcl_file=0; new_project_node->pro_ignore_o=0; new_project_node->pro_valid_options=0; if (first_project_node==NULL) first_project_node=new_project_node; else last_project_node->pro_next=new_project_node; last_project_node=new_project_node; return new_project_node; } static P_NODE add_dependency (DEP_LIST *dependency_list_p,char *dependent_module) { DEP_LIST new_dependency,dependency; P_NODE project_node; for_l (dependency,*dependency_list_p,dep_next) if (!strcmp (dependent_module,dependency->dep_node->pro_fname)) return NULL; new_dependency=memory_allocate (sizeof (struct dep_list)); for_l (project_node,first_project_node,pro_next) if (!strcmp (dependent_module,project_node->pro_fname)) break; if (project_node==NULL) project_node=add_project_node (dependent_module); new_dependency->dep_node=project_node; new_dependency->dep_next=*dependency_list_p; *dependency_list_p=new_dependency; return project_node; } static char *clean_path_list,clean_path_list_copy[PATH_LIST_STRING_SIZE]; static char *clean_lib_path,clean_lib_path_copy[PATH_NAME_STRING_SIZE]; #ifdef NB char *clean_abc_path; static char *clean_o_path; #else static char *clean_abc_path,*clean_o_path; #endif #if defined (OS2) && !defined (OMF) static char gcc_lib_path_copy[PATH_NAME_STRING_SIZE]; #endif static int verbose=0; static int silent=0; #if MACINTOSH # define DIRECTORY_SEPARATOR_STRING ":" # define DIRECTORY_SEPARATOR_CHAR ':' # define PATH_SEPARATOR_CHAR ',' #else # if defined (OS2) || defined (_WINDOWS_) # define DIRECTORY_SEPARATOR_STRING "\\" # define DIRECTORY_SEPARATOR_CHAR '\\' # define PATH_SEPARATOR_CHAR ';' # else # define DIRECTORY_SEPARATOR_STRING "/" # define DIRECTORY_SEPARATOR_CHAR '/' # define PATH_SEPARATOR_CHAR ':' # endif #endif #if MACINTOSH # undef TEST # ifdef TEST unsigned long f_get_f_info_time=0; int f_get_f_info_count=0; # endif static unsigned long get_file_time (char *fname,int wd_ref_num) { FileParam fpb; char fn[256]; int err; strcpy (fn, fname); fpb.ioNamePtr=c2pstr (fn); fpb.ioFDirIndex=0; fpb.ioFVersNum=0; fpb.ioVRefNum=wd_ref_num; # ifdef TEST { unsigned long begin_time=TickCount(); # endif err=PBGetFInfoSync ((ParmBlkPtr)&fpb); # ifdef TEST f_get_f_info_time+=TickCount()-begin_time; printf ("t=%d %d\n",f_get_f_info_time,++f_get_f_info_count); } # endif if (err) return 0; else return fpb.ioFlMdDat; } struct path_list { short path_wd_ref_num; short path_clean_system_files_wd_ref_num; struct path_list * path_next; # ifdef __MWERKS__ char path_name[]; # else char path_name[0]; # endif }; static struct path_list *path_list; static unsigned char *copy_c_to_p_string (char *c_string,char *p_string) { char *s,*d,c; d=p_string+1; s=c_string; while (c=*s++, c!='\0') *d++=c; *p_string=s-1-c_string; return (unsigned char*) p_string; } static void add_directory_to_path_list (char *path_name) { short wd_ref_num,clean_system_files_wd_ref_num; struct path_list *new_path,**last_path_p; int path_name_length; char p_string [256]; CInfoPBRec fpb; WDPBRec wd_pb; int err,root_path; root_path=0; if (path_name){ char *p; for (p=path_name; *p!=DIRECTORY_SEPARATOR_CHAR && *p!='\0'; ++p) ; if (*p=='\0'){ root_path=1; p[0]=DIRECTORY_SEPARATOR_CHAR; p[1]='\0'; } fpb.hFileInfo.ioNamePtr=copy_c_to_p_string (path_name,p_string); } else fpb.hFileInfo.ioNamePtr=(unsigned char*)"\001:"; fpb.hFileInfo.ioVRefNum =0; fpb.hFileInfo.ioFDirIndex=0; fpb.hFileInfo.ioDirID=0; err = PBGetCatInfoSync (&fpb); if (err!=0){ if (path_name) error_s ("folder '%s' does not exist",path_name); return; } wd_pb.ioNamePtr=fpb.hFileInfo.ioNamePtr; wd_pb.ioWDProcID='ClCo'; wd_pb.ioVRefNum=0; wd_pb.ioWDDirID=0; /* wd_pb.ioVRefNum=fpb.hFileInfo.ioVRefNum; wd_pb.ioWDDirID=fpb.hFileInfo.ioDirID; */ err = PBOpenWD (&wd_pb,0); if (err!=0){ if (path_name) error_s ("folder '%s' does not exist",path_name); return; } wd_ref_num=wd_pb.ioVRefNum; # ifndef NO_CLEAN_SYSTEM_FILES_FOLDERS if (path_name) if (root_path) strcat (path_name,"Clean System Files"); else strcat (path_name,":Clean System Files"); else path_name="Clean System Files"; fpb.hFileInfo.ioNamePtr=copy_c_to_p_string (path_name,p_string); fpb.hFileInfo.ioVRefNum =0; fpb.hFileInfo.ioFDirIndex=0; fpb.hFileInfo.ioDirID=0; err = PBGetCatInfoSync (&fpb); if (err!=0){ if (path_name) error_s ("folder '%s' does not exist",path_name); return; } wd_pb.ioNamePtr=fpb.hFileInfo.ioNamePtr; wd_pb.ioWDProcID='ClCo'; wd_pb.ioVRefNum=0; wd_pb.ioWDDirID=0; err = PBOpenWD (&wd_pb,0); if (err!=0){ if (path_name) error_s ("folder '%s' does not exist",path_name); return; } clean_system_files_wd_ref_num=wd_pb.ioVRefNum; path_name_length=strlen (path_name)-strlen (":Clean System Files"); if (path_name_length<0) path_name_length=0; path_name[path_name_length]='\0'; # else clean_system_files_wd_ref_num=0; if (path_name==NULL) path_name=""; path_name_length=strlen (path_name); # endif new_path=memory_allocate (sizeof (struct path_list)+1+path_name_length); last_path_p=&path_list; while (*last_path_p) last_path_p=&(*last_path_p)->path_next; new_path->path_wd_ref_num=wd_ref_num; new_path->path_clean_system_files_wd_ref_num=clean_system_files_wd_ref_num; strcpy (new_path->path_name,path_name); new_path->path_next=NULL; *last_path_p=new_path; } #if defined (MAKE_MPW_TOOL) && defined (NB) static char *main_module_path; #endif static void initialise_path_list (void) { char path[PATH_NAME_STRING_SIZE]; char *s,*path_elem; int c; path_list=NULL; if (clean_abc_path) add_directory_to_path_list (clean_abc_path); # if defined (MAKE_MPW_TOOL) && defined (NB) add_directory_to_path_list (main_module_path); # else add_directory_to_path_list (NULL); # endif s = clean_path_list; if (s!=NULL){ path_elem = s; for (c=*s; ; c=*s){ if (c==PATH_SEPARATOR_CHAR || c == '\0'){ char *s_p,*d_p; d_p=path; s_p=path_elem; while (s_p!=s) *d_p++ = *s_p++; *d_p='\0'; add_directory_to_path_list (path); if (c == '\0') break; path_elem = ++s; } else ++s; } } } static int last_path_clean_system_files_wd_ref_num_defined; static short last_path_clean_system_files_wd_ref_num; static unsigned long find_file (char *file_name,char *extension,char *complete_file_name) { unsigned long file_time; if (file_name[0]!=DIRECTORY_SEPARATOR_CHAR){ struct path_list *path_elem; # if USE_PATH_CACHE int dcl_file; # endif # ifdef NB int abc_or_obj_file; # endif strcpy (complete_file_name,file_name); strcat (complete_file_name,extension); # if USE_PATH_CACHE dcl_file= extension[0]=='.' && extension[1]=='d' && extension[2]=='c' && extension[3]=='l' && extension[4]=='\0'; if (dcl_file){ struct search_dcl_path_in_cache_result r; if (search_dcl_path_in_cache (file_name,&r)){ short wd_ref_num; wd_ref_num=r.wd_ref_num; file_time=r.file_time; last_path_clean_system_files_wd_ref_num_defined=1; last_path_clean_system_files_wd_ref_num=r.clean_system_files_wd_ref_num; strcpy (complete_file_name,r.path); if (complete_file_name[0]!='\0' && complete_file_name[strlen (complete_file_name)-1]!=DIRECTORY_SEPARATOR_CHAR) strcat (complete_file_name,DIRECTORY_SEPARATOR_STRING); strcat (complete_file_name,file_name); strcat (complete_file_name,extension); return file_time; } } # endif # ifdef NB abc_or_obj_file = extension[0]=='.' && ( (extension[1]=='a' && extension[2]=='b' && extension[3]=='c' && extension[4]=='\0') || (extension[1]=='o' && extension[2]=='b' && extension[3]=='j') ) ; for (path_elem=(clean_abc_path!=NULL && !abc_or_obj_file && path_list!=NULL) ? path_list->path_next : path_list; path_elem!=NULL; path_elem=(clean_abc_path!=NULL && abc_or_obj_file) ? NULL :path_elem->path_next) # else for (path_elem:q =path_list; path_elem!=NULL;path_elem=path_elem->path_next) # endif { short wd_ref_num; wd_ref_num=path_elem->path_wd_ref_num; file_time=get_file_time (complete_file_name,wd_ref_num); if (file_time){ last_path_clean_system_files_wd_ref_num_defined=1; last_path_clean_system_files_wd_ref_num=path_elem->path_clean_system_files_wd_ref_num; strcpy (complete_file_name,path_elem->path_name); if (complete_file_name[0]!='\0' && complete_file_name[strlen (complete_file_name)-1]!=DIRECTORY_SEPARATOR_CHAR) strcat (complete_file_name,DIRECTORY_SEPARATOR_STRING); strcat (complete_file_name,file_name); strcat (complete_file_name,extension); # if USE_PATH_CACHE if (dcl_file) cache_dcl_path (file_name,wd_ref_num,last_path_clean_system_files_wd_ref_num,file_time,path_elem->path_name); # endif return file_time; } } # ifdef NB return 0; # endif } strcpy (complete_file_name,file_name); strcat (complete_file_name,extension); return get_file_time (complete_file_name,0); } static unsigned long find_clean_system_file (char *file_name,char *extension,char *complete_file_name) { #ifdef NO_CLEAN_SYSTEM_FILES_FOLDERS return find_file (file_name,extension,complete_file_name); #else unsigned long file_time; last_path_clean_system_files_wd_ref_num_defined=0; file_time=find_file (file_name,".dcl",complete_file_name); if (!file_time) file_time=find_file (file_name,".icl",complete_file_name); if (file_time){ char *p,*last_colon; last_colon=complete_file_name; p=complete_file_name; while (*p){ if (*p==DIRECTORY_SEPARATOR_CHAR) last_colon=p+1; ++p; } # ifndef NO_CLEAN_SYSTEM_FILES_FOLDERS strcpy (last_colon,"Clean System Files" DIRECTORY_SEPARATOR_STRING); # else *last_colon='\0'; # endif strcat (last_colon,file_name); strcat (last_colon,extension); if (last_path_clean_system_files_wd_ref_num_defined){ char file_name_with_extension[PATH_NAME_STRING_SIZE]; strcpy (file_name_with_extension,file_name); strcat (file_name_with_extension,extension); file_time=get_file_time (file_name_with_extension,last_path_clean_system_files_wd_ref_num); } else file_time=get_file_time (complete_file_name,0); } return file_time; #endif } #else # ifdef _WINDOWS_ static int file_exists (char *file_name,FileTime *time_p) { HANDLE h; # ifdef GNU_C WIN32_FIND_DATAA find_data; h=FindFirstFileA (file_name,&find_data); # else WIN32_FIND_DATA find_data; h=FindFirstFile (file_name,&find_data); # endif if (h!=INVALID_HANDLE_VALUE){ FindClose (h); *time_p=find_data.ftLastWriteTime; return 1; } else return 0; } # endif # ifdef OS2 static int file_exists (char *file_name) { FILESTATUS3 fstatus; APIRET rc; rc = DosQueryPathInfo (file_name,FIL_STANDARD,&fstatus,sizeof (FILESTATUS3)); return rc==NO_ERROR; } # endif int find_file (char *file_name,char *extension,char *complete_file_name,char *first_path # ifdef _WINDOWS_ ,FileTime *file_time_p # endif ) { if (file_name[0]!=DIRECTORY_SEPARATOR_CHAR){ if (first_path!=NULL){ strcpy (complete_file_name,first_path); strcat (complete_file_name,DIRECTORY_SEPARATOR_STRING); strcat (complete_file_name,file_name); strcat (complete_file_name,extension); # ifdef _WINDOWS_ if (file_exists (complete_file_name,file_time_p)) # else # ifdef OS2 if (file_exists (complete_file_name)) # else if (access (complete_file_name,F_OK)==0) # endif # endif return 1; } if (clean_path_list!=NULL){ char *s; int c; s=clean_path_list; c=*s++; while (c!='\0'){ char *p; p=complete_file_name; while (c!=PATH_SEPARATOR_CHAR && c!='\0'){ *p++=c; c=*s++; } *p++=DIRECTORY_SEPARATOR_CHAR; strcpy (p,file_name); strcat (p,extension); # ifdef _WINDOWS_ if (file_exists (complete_file_name,file_time_p)) # else # ifdef OS2 if (file_exists (complete_file_name)) # else if (access (complete_file_name,F_OK)==0) # endif # endif return 1; if (c==PATH_SEPARATOR_CHAR) c=*s++; } } # if 0 strcpy (complete_file_name,clean_lib_path); strcat (complete_file_name,DIRECTORY_SEPARATOR_STRING "stdenv" DIRECTORY_SEPARATOR_STRING); strcat (complete_file_name,file_name); strcat (complete_file_name,extension); # ifdef _WINDOWS_ if (file_exists (complete_file_name,file_time_p)) # else # ifdef OS2 if (file_exists (complete_file_name)) # else if (access (complete_file_name,F_OK)==0) # endif # endif return 1; # endif #ifdef OS2 if (window_application){ int length; char *lib_p; strcpy (complete_file_name,clean_lib_path); length=strlen (complete_file_name); lib_p=&complete_file_name[length-3]; if (length>3 && (lib_p[0] & 0xdf)=='L' && (lib_p[1] & 0xdf)=='I' && (lib_p[2] & 0xdf)=='B'){ strcpy (lib_p,"CleanIO\\"); strcat (lib_p,file_name); strcat (lib_p,extension); if (file_exists (complete_file_name)) return 1; strcpy (lib_p,"OsIO\\"); strcat (lib_p,file_name); strcat (lib_p,extension); if (file_exists (complete_file_name)) return 1; } } #endif } strcpy (complete_file_name,file_name); strcat (complete_file_name,extension); # ifdef _WINDOWS_ return file_exists (complete_file_name,file_time_p); # else # ifdef OS2 return file_exists (complete_file_name); # else return access (complete_file_name,F_OK)==0; # endif # endif } static void replace_file_name_in_path (char *path,char *file_name,char *extension) { char *p,*last_colon; last_colon=path; p=path; while (*p){ if (*p==DIRECTORY_SEPARATOR_CHAR) last_colon=p+1; ++p; } strcpy (last_colon,file_name); strcat (last_colon,extension); } static void add_clean_system_files_and_replace_file_name_in_path (char *path,char *file_name,char *extension) { char *p,*last_colon; last_colon=path; p=path; while (*p){ if (*p==DIRECTORY_SEPARATOR_CHAR) last_colon=p+1; ++p; } # ifndef NO_CLEAN_SYSTEM_FILES_FOLDERS strcpy (last_colon,"Clean System Files" DIRECTORY_SEPARATOR_STRING); # else *last_colon='\0'; # endif strcat (last_colon,file_name); strcat (last_colon,extension); } int find_clean_system_file (char *file_name,char *extension,char *complete_file_name,char *first_path # ifdef _WINDOWS_ ,FileTime *file_time_p # endif ) { int found; found=find_file (file_name,".dcl",complete_file_name,first_path # ifdef _WINDOWS_ ,file_time_p # endif ); if (!found) found=find_file (file_name,".icl",complete_file_name,first_path # ifdef _WINDOWS_ ,file_time_p # endif ); if (found){ add_clean_system_files_and_replace_file_name_in_path (complete_file_name,file_name,extension); # ifdef _WINDOWS_ return file_exists (complete_file_name,file_time_p); # else # ifdef OS2 return file_exists (complete_file_name); # else return access (complete_file_name,F_OK)==0; # endif # endif } return found; } #endif #ifdef OS2 static char *clm_file_name; #endif static void need_file(char *file_name,char *extension,char *complete_file_name) { if (!find_clean_system_file (file_name, extension,complete_file_name,NULL)){ fprintf (stderr,"Couldn't find %s%s\n", file_name, extension); exit (1); } } static void get_paths (void) { #if MACINTOSH clean_path_list = NULL; clean_lib_path = NULL; #else clean_path_list=getenv ("CLEANPATH"); if (clean_path_list!=NULL) clean_path_list=strcpy (clean_path_list_copy,clean_path_list); else clean_path_list=clean_directory_list; # ifdef OS2 { int l; clean_lib_path=clean_lib_path_copy; l=strlen (clm_file_name); if (l=0; --n) if (clean_lib_path_copy[n]=='\\'){ clean_lib_path_copy[n]='\0'; l=n; break; } if (clean_lib_path_copy[l-4]=='\\' && (clean_lib_path_copy[l-3] & 0xdf)=='B' && (clean_lib_path_copy[l-2] & 0xdf)=='I' && (clean_lib_path_copy[l-1] & 0xdf)=='N') { clean_lib_path_copy[l-3]+='l'-'b'; clean_lib_path_copy[l-2]+='i'-'i'; clean_lib_path_copy[l-1]+='b'-'n'; } } else { clean_lib_path_copy[0]='.'; clean_lib_path_copy[1]='\0'; } } # else clean_lib_path=getenv ("CLEANLIB"); if (clean_lib_path!=NULL) clean_lib_path=strcpy (clean_lib_path_copy,clean_lib_path); else clean_lib_path=clean_lib_directory; # endif #endif #if MACINTOSH clean_abc_path=NULL; clean_o_path=NULL; #else clean_abc_path=getenv ("CLEANABCPATH"); clean_o_path=getenv ("CLEANOPATH"); #endif #if defined (OS2) && !defined (OMF) { char *gcc_lib_path; gcc_lib_path=getenv ("GCCLIB"); if (gcc_lib_path!=NULL) gcc_lib_path=strcpy (gcc_lib_path_copy,gcc_lib_path); else gcc_lib_path=gcc_lib_directory; gcc_lib_directory_arg[0]='-'; gcc_lib_directory_arg[1]='L'; strcpy (&gcc_lib_directory_arg[2], gcc_lib_path); sprintf (crt0_file_name,"%s\\crt0.o",&gcc_lib_directory_arg[2]); } #endif } static int get_abc_time (P_NODE project_node,FileTime *time_p) { char file_name[PATH_NAME_STRING_SIZE]; FileTime time; if (project_node->pro_valid_abc_time) time=project_node->pro_abc_time; else { if (project_node->pro_no_abc_file) return 0; #if MACINTOSH time=find_clean_system_file (project_node->pro_fname,".abc",file_name); if (time==0){ project_node->pro_no_abc_file=1; return 0; } #else # ifdef _WINDOWS_ if (!find_clean_system_file (project_node->pro_fname,".abc",file_name,clean_abc_path,&time)) return 0; # else { struct stat stat_buffer; if (!find_clean_system_file (project_node->pro_fname,".abc",file_name,clean_abc_path)) return 0; if (stat (file_name,&stat_buffer)<0){ project_node->pro_no_abc_file=1; return 0; } time=stat_buffer.st_mtime; } # endif #endif project_node->pro_abc_time=time; project_node->pro_valid_abc_time=1; } *time_p=time; return 1; } static int get_dcl_time (P_NODE project_node,FileTime *time_p) { char file_name[PATH_NAME_STRING_SIZE]; FileTime time; if (project_node->pro_valid_dcl_time) time=project_node->pro_dcl_time; else { if (project_node->pro_no_dcl_file) return 0; #if MACINTOSH time=find_file (project_node->pro_fname,".dcl",file_name); if (time==0){ project_node->pro_no_dcl_file=1; return 0; } #else # ifdef _WINDOWS_ if (!find_file (project_node->pro_fname,".dcl",file_name,NULL,&time)) return 0; # else { struct stat stat_buffer; if (!find_file (project_node->pro_fname,".dcl",file_name,NULL)) return 0; if (stat (file_name,&stat_buffer)<0){ project_node->pro_no_dcl_file=1; return 0; } time=stat_buffer.st_mtime; } # endif #endif project_node->pro_dcl_time=time; project_node->pro_valid_dcl_time=1; } *time_p=time; return 1; } #if MACINTOSH static int get_time (P_NODE project_node,char *extension,FileTime *time_p) { char file_name[PATH_NAME_STRING_SIZE]; unsigned long time; time=find_file (project_node->pro_fname,extension,file_name); if (time==0) return 0; *time_p=time; return 1; } static int get_clean_system_time (P_NODE project_node,char *extension,FileTime *time_p) { char file_name[PATH_NAME_STRING_SIZE]; unsigned long time; time=find_clean_system_file (project_node->pro_fname,extension,file_name); if (time==0) return 0; *time_p=time; return 1; } #else static int get_time (P_NODE project_node,char *extension,FileTime *time_p,char *first_path) { char file_name[PATH_NAME_STRING_SIZE]; # ifdef _WINDOWS_ return find_file (project_node->pro_fname,extension,file_name,first_path,time_p); # else struct stat stat_buffer; if (!find_file (project_node->pro_fname,extension,file_name,first_path)) return 0; if (stat (file_name,&stat_buffer)<0) return 0; *time_p=stat_buffer.st_mtime; return 1; # endif } static int get_clean_system_time (P_NODE project_node,char *extension,FileTime *time_p,char *first_path) { char file_name[PATH_NAME_STRING_SIZE]; # ifdef _WINDOWS_ return find_clean_system_file (project_node->pro_fname,extension,file_name,first_path,time_p); # else struct stat stat_buffer; if (!find_clean_system_file (project_node->pro_fname,extension,file_name,first_path)) return 0; if (stat (file_name,&stat_buffer)<0) return 0; *time_p=stat_buffer.st_mtime; return 1; # endif } #endif FILE *abc_file; int last_char; static int open_abc_file (P_NODE project_node) { char file_name [PATH_NAME_STRING_SIZE]; FILE *f; #if MACINTOSH if (!find_clean_system_file (project_node->pro_fname,".abc",file_name)) return 0; #else # ifdef _WINDOWS_ { FileTime time; if (!find_clean_system_file (project_node->pro_fname,".abc",file_name,clean_abc_path,&time)) return 0; } # else if (!find_clean_system_file (project_node->pro_fname,".abc",file_name,clean_abc_path)) return 0; # endif #endif f=fopen (file_name,"r"); if (f==NULL) return 0; setvbuf (f,NULL,_IOFBF,2048); last_char=getc (f); abc_file=f; return 1; } static void skip_spaces (void) { while (last_char==' ' || last_char=='\t') last_char=getc (abc_file); } static void skip_to_next_line (void) { while (last_char!='\n' && last_char!=EOF) last_char=getc (abc_file); if (last_char=='\n') last_char=getc (abc_file); } static int last_char_was (int c) { if (last_char==c){ last_char=getc (abc_file); return 1; } else return 0; } static int last_char_was_digit (void) { if (last_char<='9' && last_char>='0'){ last_char=getc (abc_file); return 1; } else return 0; } static int get_version_and_options_of_abc_file (P_NODE project_node,int *version_p) { int version,options; while (last_char!=EOF){ skip_spaces(); if (last_char!='.') return 0; last_char=getc (abc_file); if (last_char_was ('c')){ if (last_char_was ('o') && last_char_was ('m') && last_char_was ('p')){ int digit_1,digit_2,digit_3; skip_spaces(); if ((digit_1=last_char,last_char_was_digit()) && (digit_2=last_char,last_char_was_digit()) && (digit_3=last_char,last_char_was_digit())) { int digit_n; version=(digit_1-'0')*100 + (digit_2-'0')*10 + (digit_3-'0'); skip_spaces(); options=0; if (last_char!='\n') for (digit_n=0; digit_n<9; ++digit_n){ if (last_char=='0') ; else if (last_char=='1') options |= (1<pro_options=options; project_node->pro_valid_options=1; *version_p=version; return 1; } } } else if (last_char_was ('e') && last_char_was ('n') && last_char_was ('d') && last_char_was ('i') && last_char_was ('n') && last_char_was ('f') && last_char_was ('o')) { return 0; } skip_to_next_line(); } return 0; } static int get_dependency_of_abc_file (char *file_name,int max_length) { while (last_char!=EOF){ skip_spaces(); if (last_char!='.') return 0; last_char=getc (abc_file); if (last_char_was ('d')){ if (last_char_was ('e') && last_char_was ('p') && last_char_was ('e') && last_char_was ('n') && last_char_was ('d')) { int n; skip_spaces(); if (last_char=='\"'){ last_char=getc (abc_file); n=0; while (last_char!='\"' && last_char!='\n' && last_char!=EOF && npro_fname); return 0; } if (!open_abc_file (project_node)) return 0; if (!get_version_and_options_of_abc_file (project_node,&version)){ close_abc_file(); return 0; } abc_options=project_node->pro_options; if (version!=VERSION){ close_abc_file(); warning_s ("Warning: %s.abc is generated with another compiler version", project_node->pro_fname); return 0; } if (!(abc_options & SYSTEM_MASK)){ if ((abc_options & PARALLEL_MASK) || !(abc_options & STACK_LAYOUT_MASK)){ if (verbose) warning_s ("(%s.abc is not sequential abc code with stack information)", project_node->pro_fname); close_abc_file(); return 0; } #if MACINTOSH if (get_time (project_node,".icl",&icl_time) && abc_time<=icl_time){ #else if (get_time (project_node,".icl",&icl_time,NULL) && FILE_TIME_LE (abc_time,icl_time)){ #endif if (verbose) warning_s ("(%s.abc is older than corresponding icl file)", project_node->pro_fname); close_abc_file(); return 0; } if (get_dcl_time (project_node,&dcl_time) && FILE_TIME_LE (abc_time,dcl_time)){ if (verbose) warning_s ("(%s.abc is older than corresponding dcl file)", project_node->pro_fname); return 0; } } if (project_node==main_project_node && ((DEBUG_MASK | STRICTNESS_ANALYSIS_MASK) & clean_options_mask & (clean_options ^ abc_options))!=0) { if (verbose) warning_s ("(%s.icl is compiled with different options)", project_node->pro_fname); close_abc_file(); return 0; } dependency_list=NULL; while (get_dependency_of_abc_file (dependent_module,PATH_NAME_STRING_SIZE-1)){ FileTime dcl_time; P_NODE dependency_node; dependency_node=add_dependency (&dependency_list,dependent_module); if (dependency_node==NULL) continue; if (!(abc_options & SYSTEM_MASK)){ if (get_dcl_time (dependency_node,&dcl_time) && FILE_TIME_LE(abc_time,dcl_time)){ if (verbose) warning_s_s ("(%s.icl conflicts with %s.dcl)",project_node->pro_fname, dependent_module); close_abc_file(); return 0; } /* if (is_system_file (dependency_node)){ long dcl_abc_time; if (get_abc_time (dependency_node,&dcl_abc_time) && abc_time<=dcl_abc_time){ if (verbose) warning_s_s ("(%s.icl conflicts with %s.abc)", project_node->pro_fname,dependency_node->pro_fname); close_abc_file(); return 0; } } */ } } close_abc_file(); project_node->pro_depend=dependency_list; if (verbose) warning_s ("(%s.abc is up to date)",project_node->pro_fname); return 1; } static int is_system_file (P_NODE project_node) { if (project_node->pro_no_abc_file) return 0; if (!project_node->pro_valid_options){ int version; FILE *old_file; old_file=abc_file; if (!open_abc_file (project_node)){ abc_file=old_file; return 0; } if (!get_version_and_options_of_abc_file (project_node,&version)){ close_abc_file(); abc_file=old_file; return 0; } close_abc_file(); abc_file=old_file; } return (project_node->pro_options & SYSTEM_MASK)!=0; } #if defined(_WINDOWS_) && defined (GNU_C) extern int wait (int*); #endif #include static int wait_for_child (pid_t pid, char *child_name, int *status_p) { int result; result=waitpid (pid, status_p, 0); if (*status_p & 255) fprintf (stderr,"%s exited abnormally\n",child_name); return result; } #if MACINTOSH extern int CallCompiler (int argc,char **argv); #endif #ifdef OS2 static char *arg_v_to_arguments (char **argv) { int arguments_length; char **argv_p,*arguments,*arg_p; arguments_length=2; for (argv_p=argv; *argv_p!=NULL; ++argv_p) arguments_length += strlen (*argv_p)+1; arguments=memory_allocate (arguments_length); if (arguments!=NULL){ arg_p=arguments; argv_p=argv; strcpy (arg_p,*argv_p); arg_p += strlen (arg_p)+1; if (*++argv_p!=NULL){ strcpy (arg_p,*argv_p); arg_p += strlen (arg_p); while (*++argv_p!=NULL){ *arg_p++ =' '; strcpy (arg_p,*argv_p); arg_p += strlen (arg_p); } } *arg_p++ = '\0'; *arg_p++ = '\0'; } return arguments; } #endif #define CACHING_COMPILER #ifdef CACHING_COMPILER #include "Clean.h" #include "cachingcompiler.h" static int compiler_started=0; static void start_compiler (void) { int r; char cocl_file_name[PATH_NAME_STRING_SIZE]; strcpy (cocl_file_name,clean_lib_path); strcat (cocl_file_name,"/cocl"); r=start_caching_compiler ((unsigned char *)cocl_file_name); if (r < 0) exit(r); } static void stop_compiler (void) { int r; r=stop_caching_compiler(); if (r < 0) exit(r); } static char *concatenate_args (char **argv) { int size; char **argv2, *p, *args; if (*argv == NULL) error ("concatenate_args: no args\n"); size=0; for (argv2=argv; *argv2!=NULL; argv2++){ char *arg; size += 1; /* '"' */ for (arg=*argv2; *arg!='\0'; arg++) if (*arg=='"') size += 2; /* '\' and '"' */ else size += 1; /* c */ size += 2; /* '"' and (' ' or '\0') */ } args=malloc(size); if (args==NULL) return NULL; p=args; for (argv2=argv; *argv2!=NULL; argv2++){ char *arg; *p++='"'; for (arg=*argv2; *arg!='\0'; arg++) if (*arg=='"') { *p++='\\'; *p++='"'; } else *p++=*arg; *p++='"'; *p++=' '; } *(p-1)='\0'; if (p-args!=size) error ("concatenate_args: fatal programming error\n"); return args; } #endif static int call_compiler (char *cocl_file_name, char **argv) { #ifdef CACHING_COMPILER int r; char *args; if (!compiler_started){ start_compiler(); compiler_started=1; } args=concatenate_args(argv); if (args != NULL) { r=call_caching_compiler ((unsigned char *)args); free (args); } else r=-1; return r>=0; #else /* ifndef CACHING_COMPILER */ int pid,r,status; pid=fork(); if (pid<0) error ("Fork failed"); if (!pid){ strcat (cocl_file_name,"/cocl"); execv (cocl_file_name,argv); error ("Can't execute the clean compiler"); } r=wait_for_child (pid, "Clean compiler",&status); return r>=0 && status==0; #endif } static int compile_project_node (P_NODE project_node) { char file_name[PATH_NAME_STRING_SIZE]; char *abc_file_name,abc_file_name_s[PATH_NAME_STRING_SIZE]; char cocl_file_name[PATH_NAME_STRING_SIZE]; char *argv[16],**arg; int options; if (!silent) printf ("Compiling %s\n",project_node->pro_fname); project_node->pro_no_abc_file=0; project_node->pro_valid_abc_time=0; #if MACINTOSH if (!find_file (project_node->pro_fname,".icl",file_name)) error_s ("Can't find %s.icl",project_node->pro_fname); #else # ifdef _WINDOWS_ { FileTime time; if (!find_file (project_node->pro_fname,".icl",file_name,NULL,&time)) error_s ("Can't find %s.icl",project_node->pro_fname); } # else if (!find_file (project_node->pro_fname,".icl",file_name,NULL)) error_s ("Can't find %s.icl",project_node->pro_fname); # endif #endif if (clean_abc_path==NULL){ #ifdef NO_CLEAN_SYSTEM_FILES int length; #endif abc_file_name=abc_file_name_s; strcpy (abc_file_name_s,file_name); #ifdef NO_CLEAN_SYSTEM_FILES length=strlen (abc_file_name_s); abc_file_name_s[length-3]='a'; abc_file_name_s[length-2]='b'; abc_file_name_s[length-1]='c'; #else { char *p,*last_colon; last_colon=abc_file_name_s; p=abc_file_name_s; while (*p){ if (*p==DIRECTORY_SEPARATOR_CHAR) last_colon=p+1; ++p; } strcpy (last_colon,"Clean System Files"); if (access (abc_file_name,F_OK)!=0){ if (mkdir (abc_file_name,0777)!=0) error_s ("Could not create directory %s\n",abc_file_name); } strcat (last_colon,DIRECTORY_SEPARATOR_STRING); strcat (last_colon,project_node->pro_fname); strcat (last_colon,".abc"); } #endif } else { abc_file_name=abc_file_name_s; strcpy (abc_file_name,clean_abc_path); #if MACINTOSH if (clean_abc_path[0]!='\0' && clean_abc_path[strlen (clean_abc_path)-1]!=DIRECTORY_SEPARATOR_CHAR) #endif strcat (abc_file_name,DIRECTORY_SEPARATOR_STRING); strcat (abc_file_name,project_node->pro_fname); strcat (abc_file_name,".abc"); } arg=argv; *arg++="cocl"; if (cocl_redirect_stdout!=NULL){ *arg++ = cocl_redirect_stdout_option; *arg++ = cocl_redirect_stdout; } if (cocl_redirect_stderr!=NULL){ *arg++ = cocl_redirect_stderr_option; *arg++ = cocl_redirect_stderr; } *arg++="-sl"; #ifndef NO_CLEAN_SYSTEM_FILES *arg++="-csf"; #endif *arg++="-P"; #if defined (MAKE_MPW_TOOL) && defined (NB) { char *cocl_path_list; int path_list_length; path_list_length=1; if (clean_abc_path!=NULL) path_list_length+=strlen (clean_abc_path)+1; if (main_module_path!=NULL) path_list_length+=strlen (main_module_path); path_list_length+=2; if (clean_path_list!=NULL) path_list_length+=strlen (clean_path_list)+2; cocl_path_list=memory_allocate (path_list_length); cocl_path_list[0]='\0'; if (clean_abc_path!=NULL) strcat (cocl_path_list,clean_abc_path); if (clean_abc_path[0]) strcat (cocl_path_list,","); if (main_module_path==NULL) strcat (cocl_path_list,":"); else strcat (cocl_path_list,main_module_path); if (clean_path_list!=NULL){ strcat (cocl_path_list,","); strcat (cocl_path_list,clean_path_list); } *arg++=cocl_path_list; #else if (clean_path_list!=NULL) { int path_list_length; char *cocl_path_list; path_list_length=strlen (clean_path_list)+3; cocl_path_list=memory_allocate (path_list_length); cocl_path_list[0]='\0'; strcat (cocl_path_list,clean_path_list); strcat (cocl_path_list,":."); *arg++=cocl_path_list; } else *arg++="."; #endif if (syntax_check) *arg++="-c"; if (progress || ((clean_options & VERBOSE_MASK)!=0)!=DEFAULT_VERBOSE) *arg++="-v"; if (((clean_options & LIST_TYPES_MASK)!=0)!=DEFAULT_LIST_TYPES) *arg++="-lt"; if (((clean_options & LIST_ALL_TYPES_MASK)!=0)!=DEFAULT_LIST_ALL_TYPES) *arg++="-lat"; if ((clean_options & REUSE_UNIQUE_NODES)!=0) *arg++="-ou"; if ((clean_options & MEMORY_PROFILE)!=0) *arg++="-pm"; if ((clean_options & TIME_PROFILE)!=0) *arg++="-pt"; if (project_node->pro_valid_options) options=project_node->pro_options; else options=DEFAULT_OPTIONS; project_node->pro_valid_options=0; if (project_node==main_project_node) options=(options & ~clean_options_mask) | (clean_options & clean_options_mask); if (nowarn || ((options & WARNING_MASK)!=0)!=DEFAULT_WARNING) *arg++="-w"; if (((options & DEBUG_MASK)!=0)!=DEFAULT_DEBUG) *arg++="-d"; if (((options & STRICTNESS_ANALYSIS_MASK)!=0)!=DEFAULT_STRICTNESS_ANALYSIS) *arg++="-sa"; if (list_strict_export_types) *arg++="-lset"; #ifdef OS2 if (window_application) *arg++="-p"; #endif if (funcmayfail_error) *arg++="-emf"; if (varnotused_error) *arg++="-enu"; if (funcnotused_error) *arg++="-efnu"; *arg++="-o"; *arg++=abc_file_name; *arg++=file_name; *arg=NULL; #if MACINTOSH r=CallCompiler (arg-argv-1,argv+1); #if defined (MAKE_MPW_TOOL) && defined (NB) if (cocl_path_list!=NULL){ free (cocl_path_list); cocl_path_list=NULL; } } # endif if (r) return 1; else return 0; #else strcpy (cocl_file_name,clean_lib_path); # if defined (OS2) || defined (_WINDOWS_) strcat (cocl_file_name,"\\cocl.exe"); argv[0]=cocl_file_name; # if defined (_WINDOWS_) # ifdef GNU_C r=spawnvp (P_WAIT,cocl_file_name,argv); if (r>=0) r=wait (&status); return r>=0 && status==0; # else return spawnv (P_WAIT,cocl_file_name,argv)==0; # endif # else { CHAR load_error [17]; RESULTCODES return_codes; APIRET rc; char *arguments; arguments=arg_v_to_arguments (argv); if (arguments!=NULL){ rc=DosExecPgm (load_error,sizeof (load_error),EXEC_SYNC,arguments,NULL,&return_codes,cocl_file_name); free (arguments); if (rc==0 && return_codes.codeTerminate==0) return return_codes.codeResult==0; } error ("Can't execute the clean compiler"); return 0; } # endif # else return call_compiler (cocl_file_name, argv); # endif #endif } #ifdef USE_TOOLSERVER #include #include #include "AERegistry.h" static int send_mpw_command (char *mpw_command) { AppleEvent the_event; OSType signature; OSErr err; AEAddressDesc target; signature = 'MPSX'; /* toolserver */ err=AECreateDesc (typeApplSignature,(Ptr)&signature,sizeof (signature),&target); if (err!=noErr) return 1; /* err; */ err=AECreateAppleEvent (kAEMiscStandards,kAEDoScript,&target,kAutoGenerateReturnID,kAnyTransactionID,&the_event); if (err!=noErr) return 2; /* err; */ err=AEPutParamPtr (&the_event,keyDirectObject,'TEXT',mpw_command,strlen (mpw_command)); if (err!=noErr) return 3; /* err; */ err=AESend (&the_event,NULL,kAEWaitReply/* kAENoReply */,kAENormalPriority,kNoTimeOut,NULL,NULL); if (err!=noErr) return err; return 0; } #endif #if MACINTOSH && !defined (G_POWER) static char *OBJECT_FILE_EXTENSION; /* # define OBJECT_FILE_EXTENSION ".obj1" */ #else # if (defined (_WINDOWS_) && (defined (USE_WLINK)) || defined (OMF)) # define OBJECT_FILE_EXTENSION ".obj" # else # define OBJECT_FILE_EXTENSION ".o" # endif #endif #if MACINTOSH extern int generate_code (int,char **); #endif static int generate_code_for_project_node (P_NODE project_node,char *file_name) { char *argv[16],**arg; if (!silent) printf ("Generating code for %s\n",project_node->pro_fname); arg=argv; *arg++="cg"; #if MACINTOSH || defined (NO_ASSEMBLE) if (only_s_files) *arg++="-a"; #endif if (check_stack_overflow) *arg++="-os"; if (check_indices) *arg++="-ci"; #if defined (MAKE_MPW_TOOL) && defined (NB) *arg++="-sane"; if (!generate_mc68020_code) *arg++="-mc68000"; #endif *arg++=file_name; *arg=NULL; #if MACINTOSH # ifdef USE_TOOLSERVER { char mpw_command[512]; int result; if (generate_code (arg-argv,argv)!=0) return 0; /* if (!silent) printf ("Assembling %s\n",project_node->pro_fname); sprintf (mpw_command,"PPCAsm -w off \'%s.a\' -o \'%s.o\'",file_name,file_name); result=send_mpw_command (mpw_command); if (result!=0){ printf ("%d\n",result); error_s ("Assembling %s failed\n",project_node->pro_fname); } { char assembly_file_name[PATH_NAME_STRING_SIZE]; extern unlink (char*); sprintf (assembly_file_name,"%s.a",file_name); unlink (assembly_file_name); } */ return 1; } # else return generate_code (arg-argv,argv)==0; # endif #else { char cg_file_name[PATH_NAME_STRING_SIZE]; strcpy (cg_file_name,clean_lib_path); # if defined (OS2) || defined (_WINDOWS_) strcat (cg_file_name,"\\cg.exe"); argv[0]=cg_file_name; # ifdef _WINDOWS_ # ifdef GNU_C { int r,status; argv[0]=cg_file_name; r=spawnvp (P_WAIT,cg_file_name,argv); if (r>=0) r=wait (&status); return r>=0 && status==0; } # else return spawnv (P_WAIT,cg_file_name,argv)==0; # endif # else { CHAR load_error [17]; RESULTCODES return_codes; APIRET rc; char *arguments; arguments=arg_v_to_arguments (argv); if (arguments!=NULL){ rc=DosExecPgm (load_error,sizeof (load_error),EXEC_SYNC,arguments,NULL,&return_codes,cg_file_name); free (arguments); if (rc==0 && return_codes.codeTerminate==0) return return_codes.codeResult==0; } error ("Can't execute the code generator"); return 0; } # endif # else { int pid,r,status; pid=fork(); if (pid<0) error ("Fork failed"); if (!pid){ strcat (cg_file_name,"/cg"); execv (cg_file_name,argv); error ("Can't execute the code generator"); } r=wait_for_child (pid, "Code generator",&status); return r>=0 && status==0; } # endif } #endif } static int assemble (P_NODE project_node,char *file_name) { int pid,r,status; char s_file_name[PATH_NAME_STRING_SIZE],o_file_name[PATH_NAME_STRING_SIZE]; if (!silent) printf ("Assembling %s\n",project_node->pro_fname); strcpy (s_file_name,file_name); strcat (s_file_name,".s"); #if ! MACINTOSH if (clean_o_path==NULL) #endif strcpy (o_file_name,file_name); #if ! MACINTOSH else { strcpy (o_file_name,clean_o_path); strcat (o_file_name,DIRECTORY_SEPARATOR_STRING); strcat (o_file_name,project_node->pro_fname); } #endif strcat (o_file_name,OBJECT_FILE_EXTENSION); #if !(defined (OS2) || defined (_WINDOWS_)) && ! MACINTOSH pid=fork(); if (pid<0) error ("Fork failed"); if (!pid) #endif { char *argv[16],**arg; arg=argv; *arg++="as"; #if defined (OS2) && defined (OMF) *arg++="-Zomf"; #endif *arg++=s_file_name; *arg++="-o"; *arg++=o_file_name; *arg=0; #if defined (OS2) || defined (_WINDOWS_) # if defined (OS2) r=dos_exec (assembler_file_name,argv,0); # else # ifdef _WINDOWS_ # ifdef GNU_C { int status; argv[0]=assembler_file_name; r=spawnvp (P_WAIT,assembler_file_name,argv); if (r>=0) r=wait (&status); return r>=0 && status==0; } # else return spawnvp (P_WAIT,assembler_file_name,argv)==0; # endif # else r=dos_exec (assembler_file_name,argv,1); # endif # endif return r==0; } #else # if MACINTOSH } return 1; # else execv (assembler_file_name,argv); error ("Can't execute the assembler"); } r=wait_for_child (pid, "Assembler",&status); return r>=0 && status==0; # endif #endif } static void get_dependencies (P_NODE project_node) { DEP_LIST dependency_list; char dependent_module [PATH_NAME_STRING_SIZE]; int version; if (!open_abc_file (project_node)) return; if (!get_version_and_options_of_abc_file (project_node,&version)){ close_abc_file(); return; } dependency_list=NULL; while (get_dependency_of_abc_file (dependent_module,PATH_NAME_STRING_SIZE-1)) add_dependency (&dependency_list,dependent_module); close_abc_file(); project_node->pro_depend=dependency_list; } static int make_project_to_abc_files (P_NODE project_node) { DEP_LIST dependency; if (project_node->pro_up_to_date) return 1; project_node->pro_up_to_date=1; if (!project_node->pro_ignore_o && !project_node_is_abc_up_to_date (project_node)){ if (is_system_file (project_node)) return 0; if (!compile_project_node (project_node)) return 0; if (!single_module) get_dependencies (project_node); } if (!single_module) for_l (dependency,project_node->pro_depend,dep_next) if (!make_project_to_abc_files (dependency->dep_node)) return 0; return 1; } static int project_node_is_o_up_to_date (P_NODE project_node) { FileTime abc_time,o_time; if (!get_clean_system_time (project_node,OBJECT_FILE_EXTENSION,&o_time #if ! MACINTOSH ,clean_o_path!=NULL ? clean_o_path : clean_abc_path #endif )) { if (verbose) warning_s ("(%s.o doesn't exist)",project_node->pro_fname); return 0; } if (get_abc_time (project_node,&abc_time) && FILE_TIME_LE (o_time,abc_time)){ if (verbose) warning_s ("(%s.o is older than corresponding abc file)", project_node->pro_fname); return 0; } if (verbose) warning_s ("(%s.o is up to date)",project_node->pro_fname); return 1; } static int make_project_to_o_files (void) { P_NODE project_node; for_l (project_node,first_project_node,pro_next){ if (project_node->pro_up_to_date && !project_node->pro_ignore_o && !project_node_is_o_up_to_date (project_node)){ char file_name[PATH_NAME_STRING_SIZE]; #if MACINTOSH if (!find_clean_system_file (project_node->pro_fname,".abc",file_name)) error_s ("Can't find %s.abc",project_node->pro_fname); #else # ifdef _WINDOWS_ { FileTime time; if (!find_clean_system_file (project_node->pro_fname,".abc",file_name,clean_abc_path,&time)) error_s ("Can't find %s.abc",project_node->pro_fname); } # else if (!find_clean_system_file (project_node->pro_fname,".abc",file_name,clean_abc_path)) error_s ("Can't find %s.abc",project_node->pro_fname); # endif #endif file_name[strlen (file_name)-4]='\0'; if (!generate_code_for_project_node (project_node,file_name)) return 0; #if ! MACINTOSH && !defined (NO_ASSEMBLE) if (!assemble (project_node,file_name)) return 0; strcat (file_name,".s"); unlink (file_name); #endif } } return 1; } static int project_node_is_s_up_to_date (P_NODE project_node) { FileTime abc_time,s_time; if (!get_clean_system_time (project_node,".s",&s_time #if ! MACINTOSH ,clean_abc_path #endif )){ if (verbose) warning_s ("(%s.s doesn't exist)",project_node->pro_fname); return 0; } if (get_abc_time (project_node,&abc_time) && FILE_TIME_LE (s_time,abc_time)){ if (verbose) warning_s ("(%s.s is older than corresponding abc file)", project_node->pro_fname); return 0; } if (verbose) warning_s ("(%s.s is up to date)",project_node->pro_fname); return 1; } static int make_project_to_s_files (void) { P_NODE project_node; for_l (project_node,first_project_node,pro_next){ if (project_node->pro_up_to_date && !project_node_is_s_up_to_date (project_node)){ char file_name[PATH_NAME_STRING_SIZE]; #if MACINTOSH if (!find_clean_system_file (project_node->pro_fname,".abc",file_name)) error_s ("Can't find %s.abc",project_node->pro_fname); #else # ifdef _WINDOWS_ { FileTime time; if (!find_clean_system_file (project_node->pro_fname,".abc",file_name,clean_abc_path,&time)) error_s ("Can't find %s.abc",project_node->pro_fname); } # else if (!find_clean_system_file (project_node->pro_fname,".abc",file_name,clean_abc_path)) error_s ("Can't find %s.abc",project_node->pro_fname); # endif #endif file_name[strlen (file_name)-4]='\0'; if (!generate_code_for_project_node (project_node,file_name)) return 0; } } return 1; } long data [] = { #ifdef M68000 0x00020107, 0x00000000, 0x00000010, 0x00000000, 0x0000003c, 0x00000000, 0x00000000, 0x00000000, 0x00200000, 0x00080000, 0x00080000, 0x00000008, 0x00000004, 0x07000000, 0x0000000c, 0x0000000b, 0x07000000, 0x00000010, 0x00000014, 0x07000000, 0x00000000, 0x0000001f, 0x07000000, 0x00000008, 0x0000002d, 0x07000000, 0x00000004, 0x0000003c, 0x5f666c61, 0x67730064, 0x6174615f, 0x656e6400, 0x5f686561, 0x705f7369, 0x7a65005f, 0x635f7374, 0x61636b5f, 0x73697a65, 0x005f6162, 0x5f737461, 0x636b5f73, 0x697a6500 #else # ifdef I486 # ifdef _WINDOWS_ # if 0 /* without _ */ 196940, 814507665, 152, 11, 17104896, 2019914798, 116, 0, 0, 0, 0, 0, 0, 0, 32, 1952539694, 97, 0, 0, 12, 140, 0, 0, 0, 64, 1936941614, 0, 12, 12, 0, 0, 0, 0, 0, 128, 11, 21, 31, 1818846766, 101, 0, 65534, 1634074983, 25963, 0, 0, 0, 0, 4, 0, 2, 2, 917504, 262144, 131072, 131072, 1734437990, 115, 8, 2, 1949171714, 7632997, 0, 65536, 16973824, 0, 0, 0, 0, 1680736256, 6386785, 0, 131072, 16973824, 12, 0, 0, 0, 1647181824, 29555, 0, 196608, 16973824, 0, 0, 0, 0, 1835008, 1701314560, 1935634529, 6650473, 1935630945, 1801675124, 2053731167, 101 # else /* with _ */ 196940, 817729185, 152, 11, 17039360, 2019914798, 116, 0, 0, 0, 0, 0, 0, 0, 1610612768, 1952539694, 97, 0, 0, 12, 140, 0, 0, 0, -1073741760, 1936941614, 0, 0, 12, 0, 0, 0, 0, 0, -1073741696, 11, 21, 31, 1818846766, 101, 0, 65534, 1634074983, 25963, 0, 0, 0, 2019914798, 116, 0, 1, 259, 0, 0, 0, 0, 1952539694, 97, 0, 2, 786691, 0, 0, 0, 0, 1936941614, 0, 12, 3, 259, 0, 0, 0, 0, 0, 4, 0, 2, 2, 983040, 262144, 131072, 131072, 1634494047, 29543, 8, 2, 1966082, 1751056384, 1601200485, 1702521203, 1650548480, 1635021663, 1935633251, 6650473 # endif # else # ifdef OMF 0x0b000d80,0x6974706f,0x2e736e6f,0xf36a626f ,0x80000688,0x4c4803a1,0x005096ba,0x45540600 ,0x32335458,0x54414406,0x05323341,0x33535342 ,0x24240932,0x424d5953,0x07534c4f,0x59542424 ,0x04534550,0x45444f43,0x54414404,0x53420341 ,0x45440653,0x4d595342,0x42454406,0x04505954 ,0x54414c46,0x52474406,0x7350554f,0xa9000798 ,0x07020000,0x0798ae01,0x000ca900,0xa0010803 ,0xa9000798,0x09040000,0x0798aa01,0x0017a900 ,0x91010a05,0xa9000798,0x0b060000,0x029aa601 ,0x9a580c00,0xff0d0006,0x5002ff03,0x01002a90 ,0x65680902,0x735f7061,0x00657a69,0x610d0000 ,0x74735f62,0x5f6b6361,0x657a6973,0x05000004 ,0x67616c66,0x00000873,0x00048805,0x9101a240 ,0x020010a0,0x00010000,0x00020000,0x00030000 ,0xa0480000,0x00040015,0x01401000,0x20202004 ,0x35100020,0x01170017,0xa02b07cc,0x1104000a ,0x00110500,0x2b000000,0x4400089d,0xc8011001 ,0x95af8c02,0x01000027,0x00000000,0x00000000 ,0x00000018,0x00000000,0x00000000,0x00000001 ,0x74706f0b,0x736e6f69,0x6a626f2e,0x00028baa ,0x00007300 # else # ifdef LINUX_ELF 0x464c457f,0x00010101,0x00000000,0x00000000, 0x00030001,0x00000001,0x00000000,0x00000000, 0x00000074,0x00000000,0x00000034,0x00280000, 0x00040007,0x00000001,0x00000004,0x00000005, 0x00000002,0x00000003,0x79732e00,0x6261746d, 0x74732e00,0x62617472,0x68732e00,0x74727473, 0x2e006261,0x74786574,0x61642e00,0x2e006174, 0x00737362,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x0000001b, 0x00000001,0x00000006,0x00000000,0x00000034, 0x00000000,0x00000000,0x00000000,0x00000004, 0x00000000,0x00000021,0x00000001,0x00000003, 0x00000000,0x00000034,0x00000014,0x00000000, 0x00000000,0x00000004,0x00000000,0x00000027, 0x00000008,0x00000003,0x00000000,0x00000048, 0x00000000,0x00000000,0x00000000,0x00000004, 0x00000000,0x00000011,0x00000003,0x00000000, 0x00000000,0x00000048,0x0000002c,0x00000000, 0x00000000,0x00000001,0x00000000,0x00000001, 0x00000002,0x00000000,0x00000000,0x0000018c, 0x00000090,0x00000006,0x00000004,0x00000004, 0x00000010,0x00000009,0x00000003,0x00000000, 0x00000000,0x0000021c,0x00000044,0x00000000, 0x00000000,0x00000001,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00010003,0x00000000, 0x00000000,0x00000000,0x00020003,0x00000000, 0x00000000,0x00000000,0x00030003,0x00000001, 0x00000000,0x00000000,0x00020011,0x0000000b, 0x00000004,0x00000000,0x00020011,0x00000019, 0x00000008,0x00000000,0x00020011,0x0000001f, 0x0000000c,0x00000000,0x00020011,0x00000032, 0x00000010,0x00000000,0x00020011,0x61656800, 0x69735f70,0x6100657a,0x74735f62,0x5f6b6361, 0x657a6973,0x616c6600,0x68007367,0x5f706165, 0x657a6973,0x6c756d5f,0x6c706974,0x6e690065, 0x61697469,0x65685f6c,0x735f7061,0x00657a69 # else 0x00640107,0x00000000,0x0000000c,0x00000000, 0x00000024,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000004, 0x00000007,0x00000000,0x0000000f,0x00000007, 0x00000004,0x0000001e,0x00000007,0x00000008, 0x00000025,0x6165685f,0x69735f70,0x5f00657a, 0x735f6261,0x6b636174,0x7a69735f,0x665f0065, 0x7367616c,0x00000000 # endif # endif # endif # else # if defined (SOLARIS) 0x7f454c46,0x01020100,0x00000000,0x00000000, 0x00010002,0x00000001,0x00000000,0x00000000, 0x000000ec,0x00000000,0x00340000,0x00000028, 0x00050001,0x002e7368,0x73747274,0x6162002e, 0x64617461,0x002e7379,0x6d746162,0x002e7374, 0x72746162,0x00000000,0x00000001,0x00000002, 0x00000003,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000001,0x0000000c,0x00000000, 0x00000002,0x00000000,0x00000000,0x00000000, 0x03000002,0x0000000a,0x00000000,0x00000000, 0x10000002,0x00000014,0x00000004,0x00000000, 0x10000002,0x00000022,0x00000008,0x00000000, 0x10000002,0x00646174,0x615f656e,0x64006865, 0x61705f73,0x697a6500,0x61625f73,0x7461636b, 0x5f73697a,0x6500666c,0x61677300,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000001,0x00000003,0x00000000, 0x00000000,0x00000034,0x00000021,0x00000000, 0x00000000,0x00000001,0x00000000,0x0000000b, 0x00000001,0x00000003,0x00000000,0x00000058, 0x0000000c,0x00000000,0x00000000,0x00000004, 0x00000000,0x00000011,0x00000002,0x00000002, 0x00000000,0x00000064,0x00000060,0x00000004, 0x00000003,0x00000004,0x00000010,0x00000019, 0x00000003,0x00000002,0x00000000,0x000000c4, 0x00000028,0x00000000,0x00000000,0x00000001, 0x00000000 # else # ifdef LINUX 0x7f454c46,0x01020100,0x00000000,0x00000000, 0x00010014,0x00000001,0x00000000,0x00000000, 0x00000074,0x00000000,0x00340000,0x00000028, 0x00070004,0x00000008,0x00200000,0x00080000, 0x00001400,0x00019000,0x002e7379,0x6d746162, 0x002e7374,0x72746162,0x002e7368,0x73747274, 0x6162002e,0x74657874,0x002e6461,0x7461002e, 0x62737300,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x0000001b, 0x00000001,0x00000006,0x00000000,0x00000034, 0x00000000,0x00000000,0x00000000,0x00000001, 0x00000000,0x00000021,0x00000001,0x00000003, 0x00000000,0x00000034,0x00000014,0x00000000, 0x00000000,0x00000001,0x00000000,0x00000027, 0x00000008,0x00000003,0x00000000,0x00000048, 0x00000000,0x00000000,0x00000000,0x00000001, 0x00000000,0x00000011,0x00000003,0x00000000, 0x00000000,0x00000048,0x0000002c,0x00000000, 0x00000000,0x00000001,0x00000000,0x00000001, 0x00000002,0x00000000,0x00000000,0x0000018c, 0x00000090,0x00000006,0x00000004,0x00000004, 0x00000010,0x00000009,0x00000003,0x00000000, 0x00000000,0x0000021c,0x00000041,0x00000000, 0x00000000,0x00000001,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x03000001,0x00000000, 0x00000000,0x00000000,0x03000002,0x00000000, 0x00000000,0x00000000,0x03000003,0x00000001, 0x00000000,0x00000000,0x11000002,0x00000007, 0x00000004,0x00000000,0x11000002,0x00000011, 0x00000008,0x00000000,0x11000002,0x0000001c, 0x0000000c,0x00000000,0x11000002,0x0000002f, 0x00000010,0x00000000,0x11000002,0x00666c61, 0x67730068,0x6561705f,0x73697a65,0x00737461, 0x636b5f73,0x697a6500,0x68656170,0x5f73697a, 0x655f6d75,0x6c746970,0x6c650069,0x6e697469, 0x616c5f68,0x6561705f,0x73697a65,0x00 # else 0x01030107,0x00000000,0x00000010,0x00000000, 0x0000003c,0x00000000,0x00000000,0x00000000, 0x00200000,0x00080000,0x00080000,0x00000008, 0x00000004,0x07000000,0x00000008,0x00000012, 0x07000000,0x0000000c,0x00000019,0x07000000, 0x00000004,0x00000028,0x07000000,0x00000000, 0x00000033,0x07000000,0x00000010,0x0000003c, 0x5f635f73,0x7461636b,0x5f73697a,0x65005f66, 0x6c616773,0x005f6162,0x5f737461,0x636b5f73, 0x697a6500,0x5f686561,0x705f7369,0x7a650064, 0x6174615f,0x656e6400 # endif # endif # endif #endif }; #define COMMENT_CHAR '#' static char *parse_word (char **line_h) { char *begin,*end; int c; begin=*line_h; while ((c = (*begin=='\\' && *(begin+1)!='\0') ? * ++begin : *begin),isspace (c)) ++begin; if (*begin==COMMENT_CHAR || *begin=='\0') return NULL; for (end=begin; !isspace ((int) *end) && *end!='\0'; ++end) if (*end=='\\' && *(end+1)!='\0') ++end; if (*end=='\0') *line_h = end; else { *line_h = end+1; *end = '\0'; } return begin; } long ab_stack_size,heap_size,flags; #ifdef MARKING_GC long heap_size_multiple=20<<8,initial_heap_size=100<<10; #endif #if ! MACINTOSH int create_options_file (char **options_file_name_p) { char *options_file_name; FILE *f; unsigned int data_size; #if defined (_WINDOWS_) || defined (OS2) options_file_name="cgopt.$$$"; # ifdef OMF { char *p; for (p=options_file_name; *p; ++p) if (*p=='/') *p='\\'; } # endif f=fopen (options_file_name,"wb"); #else { static char cgopt_file_name[]="/tmp/cgoptXXXXXX"; int options_fd; options_fd=mkstemp (cgopt_file_name); if (options_fd<0) return 0; options_file_name=cgopt_file_name; f=fdopen (options_fd,"wb"); } #endif if (f==NULL) error_s ("Can't create options file %s",options_file_name); #if defined (SOLARIS) data[22]=heap_size; data[23]=ab_stack_size; data[24]=flags; data_size=sizeof (data); #else # if defined (LINUX_ELF) data[13]=heap_size; data[14]=ab_stack_size; data[15]=flags; data[16]=heap_size_multiple; data[17]=initial_heap_size; data_size=sizeof (data); # elif defined (LINUX) && defined (POWERPC) data[13]=flags; data[14]=heap_size; data[15]=ab_stack_size; data[16]=heap_size_multiple; data[17]=initial_heap_size; data_size=sizeof (data); # else # ifdef _WINDOWS_ data[35]=heap_size; data[36]=ab_stack_size; data[37]=flags; # if 0 /* without _ */ data_size=sizeof (data)-2; # else /* with _ */ data_size=sizeof (data); # endif # else # ifdef OMF *(long*)((char*)data+230)=heap_size; *(long*)((char*)data+234)=ab_stack_size; *(long*)((char*)data+238)=flags; data_size=sizeof (data)-2; # else data[8]=heap_size; data[9]=ab_stack_size; # ifdef I486 data[10]=flags; data_size=sizeof (data)-3; # else data[10]=512<<10; data[11]=flags; data_size=sizeof (data); # endif # endif # endif # endif #endif if (fwrite (data,1,data_size,f)!=data_size){ fclose (f); unlink (options_file_name); error ("Error writing options file"); } if (fclose (f)!=0){ unlink (options_file_name); error ("Error writing options file"); } *options_file_name_p=options_file_name; return 1; } #else #include static void remove_resources (ResType resource_type) { SetResLoad (0); while (Count1Resources (resource_type)>0){ Handle resource; resource=Get1IndResource (resource_type,1); if (resource==NULL || ResError()){ SetResLoad (1); error ("Error while removing resources from application file"); } RmveResource (resource); if (ResError()){ SetResLoad (1); error ("Error while removing resources from application file"); } } SetResLoad (1); } static int add_stack_and_size_resource_to_resource_file (void) { Handle size_handle; unsigned short *size_p; Handle stack_handle; unsigned long *stack_p; unsigned long size; remove_resources ('SIZE'); remove_resources ('STCK'); stack_handle=NewHandle (16); if (stack_handle==NULL) return 0; size_handle=NewHandle (10); if (size_handle==NULL){ DisposeHandle (stack_handle); return 0; } stack_p=(unsigned long*)*stack_handle; *stack_p++=ab_stack_size; *stack_p++=0; *stack_p++=heap_size; *stack_p=flags; size_p=(unsigned short*)*size_handle; *size_p++=0; size = ab_stack_size + heap_size + 160*1024; size = (size+3l) & ~3l; *(*(unsigned long**)&size_p)++= size; *(*(unsigned long**)&size_p)++= size; AddResource (stack_handle,'STCK',0,(ConstStr255Param)"\p"); if (ResError()){ DisposeHandle (stack_handle); DisposeHandle (size_handle); return 0; } AddResource (size_handle,'SIZE',-1,(ConstStr255Param)"\p"); if (ResError()){ ReleaseResource (stack_handle); DisposeHandle (size_handle); return 0; } ReleaseResource (stack_handle); if (ResError()){ ReleaseResource (size_handle); return 0; } ReleaseResource (size_handle); if (ResError()) return 0; return 1; } static int add_stack_and_size_resource_to_application (char *application_file_name) { int resource_file_n,error; char resource_file_name[256]; if (application_file_name!=NULL) copy_c_to_p_string (application_file_name,resource_file_name); else copy_c_to_p_string ("hd:desktop folder:a",resource_file_name); resource_file_n=HOpenResFile (0,0,(ConstStr255Param)resource_file_name,fsRdWrPerm); if (resource_file_n==-1) return 0; error=add_stack_and_size_resource_to_resource_file(); CloseResFile (resource_file_n); if (ResError()) return 0; return error; } #endif #if MACINTOSH && !defined (G_POWER) extern int link_application_argc_argv (int,char **); #endif #ifdef OPTIMISE_LINK static char *linker_output_object_file_name; #endif #ifdef USE_TOOLSERVER static char *append_string (char *s1,char *s2) { char c; while (c=*s2++,c!='\0') *s1++=c; return s1; } # define USE_METROWERKS_LINKER 0 static int link_project_toolserver (P_NODE first_project_node,char *options_file_name,char *application_file_name) { P_NODE project_node; char o_file_name[PATH_NAME_STRING_SIZE]; struct library_list *library; char *mpw_command,*p; mpw_command=malloc (8192); if (mpw_command==NULL) error ("Out of memory"); if (!silent) printf ("Linking %s\n",main_project_node->pro_fname); # if USE_METROWERKS_LINKER p=append_string (mpw_command,"MWLinkPPC >= PPCLinkErrors -o "); # else p=append_string (mpw_command,"PPCLink -mf >= PPCLinkErrors -o "); # endif if (application_file_name!=NULL){ p=append_string (p,application_file_name); } else p=append_string (p,"\'hd:desktop folder:a\'"); *p++=' '; *p++='\''; p=append_string (p,clean_lib_path); p=append_string (p,":Clean System Files:_startup" OBJECT_FILE_EXTENSION); *p++='\''; *p++=' '; *p++='\''; p=append_string (p,clean_lib_path); p=append_string (p,":Clean System Files:_system" OBJECT_FILE_EXTENSION); *p++='\''; for_l (project_node,first_project_node,pro_next){ if (project_node->pro_up_to_date && !(project_node->pro_ignore_o)){ if (!find_clean_system_file (project_node->pro_fname,OBJECT_FILE_EXTENSION,o_file_name)) error_s ("Can't find %s" OBJECT_FILE_EXTENSION,project_node->pro_fname); *p++=' '; *p++='\''; p=append_string (p,o_file_name); *p++='\''; } } p=append_string (p, " \'Applications:MPW:Libraries:SharedLibraries:InterfaceLib\'" " \'Applications:MPW:Libraries:PPCLibraries:MathLib.xcoff\'" " \'Applications:MPW:Libraries:SharedLibraries:StdCLib\'" " \'Applications:MPW:Libraries:PPCLibraries:StdCRuntime.o\'" " \'Applications:MPW:Libraries:PPCLibraries:PPCCRuntime.o\'" # if !USE_METROWERKS_LINKER " -librename MathLib.xcoff=MathLib" # endif " -main __start"); *p='\0'; if (send_mpw_command (mpw_command)!=0){ free (mpw_command); error ("Linking failed"); return 0; } /* p=append_string (mpw_command,"makePEF >= MakePEFErrors "); if (application_file_name!=NULL){ p=append_string (p,application_file_name); p=append_string (p,".xcoff"); p=append_string (p," -o "); p=append_string (p,application_file_name); } else { p=append_string (p,"\'hd:desktop folder:a.xcoff\'"); p=append_string (p," -o "); p=append_string (p,"\'hd:desktop folder:a\'"); } p=append_string (p, " -l InterfaceLib.xcoff=InterfaceLib" " -l MathLib.xcoff=MathLib" " -l StdCLib.xcoff=StdCLib" " -ft APPL -fc \'????\'"); *p='\0'; if (send_mpw_command (mpw_command)!=0){ free (mpw_command); error ("Making PEF failed"); return 0; } */ free (mpw_command); return 1; } #endif #if !(defined (MAKE_MPW_TOOL) || defined (USE_TOOLSERVER)) static int link_project (P_NODE first_project_node,char *options_file_name,char *application_file_name) { P_NODE project_node; char o_file_name[PATH_NAME_STRING_SIZE],system_file_name[PATH_NAME_STRING_SIZE]; char *argv[1024],**arg; struct library_list *library; # if (defined (_WINDOWS_) && !defined (USE_WLINK)) || defined (OMF) # if defined (NO_CLIB) char startup0_file_name[PATH_NAME_STRING_SIZE]; # endif char startup1_file_name[PATH_NAME_STRING_SIZE],startup2_file_name[PATH_NAME_STRING_SIZE]; # else char start_up_file_name[PATH_NAME_STRING_SIZE]; # endif # ifdef sparc char reals_file_name[PATH_NAME_STRING_SIZE]; # endif # ifdef OS2 char clean_resources_file_name[PATH_NAME_STRING_SIZE], clean_def_file_name[PATH_NAME_STRING_SIZE],appl_file_name[PATH_NAME_STRING_SIZE]; # ifndef OMF char os2_interface_file_name[PATH_NAME_STRING_SIZE]; # endif # ifdef NO_CLIB char os2lib_file_name[PATH_NAME_STRING_SIZE]; # endif int l; # endif # if defined (_WINDOWS_) && defined (USE_WLINK) char w_crt0_file_name[PATH_NAME_STRING_SIZE]; # endif # if defined (_WINDOWS_) || defined (OS2) char stack_option[32]; # endif # if defined (USE_CLEANLINKER) char kernel32_file_name[PATH_NAME_STRING_SIZE]; char user32_file_name[PATH_NAME_STRING_SIZE]; char gdi32_file_name[PATH_NAME_STRING_SIZE]; # endif # ifdef SOLARIS char crt [128], crti [128], crtn [128]; # endif if (!silent) printf ("Linking %s\n",main_project_node->pro_fname); # ifdef OPTIMISE_LINK { static char linker_output_file_name[]="/tmp/linkerXXXXXX"; int linker_output_fd; linker_output_fd=mkstemp (linker_output_file_name); if (linker_output_fd<0){ error_s ("Can't create %s",linker_output_file_name); return 0; } close (linker_output_fd); linker_output_object_file_name=linker_output_file_name; } arg=argv; *arg++="linker"; *arg++=linker_output_object_file_name; need_file ("_startup",OBJECT_FILE_EXTENSION,start_up_file_name); *arg++=start_up_file_name; need_file ("_system",OBJECT_FILE_EXTENSION,system_file_name); *arg++=system_file_name; for_l (project_node,first_project_node,pro_next){ if (project_node->pro_up_to_date && !project_node->pro_ignore_o){ char *file_name; if (!find_clean_system_file (project_node->pro_fname,OBJECT_FILE_EXTENSION,o_file_name, clean_o_path!=NULL ? clean_o_path : clean_abc_path )) { error_s ("Can't find %s.o",project_node->pro_fname); } file_name=memory_allocate (strlen (o_file_name)+1); strcpy (file_name,o_file_name); *arg++=file_name; } } for_l (library,first_library,library_next){ int s; s=strlen (library->library_file_name); if (s>=2 && library->library_file_name[0]!=':' && library->library_file_name[s-2]=='.' && library->library_file_name[s-1]=='o') *arg++=library->library_file_name; } *arg=NULL; { int pid,r,status; # if 0 char **a; a=argv; while (*a){ printf ("%s\n",*a); ++a; } # endif pid=fork(); if (pid<0) error ("Fork failed"); if (!pid){ char linker_file_name_[PATH_NAME_STRING_SIZE]; strcpy (linker_file_name_,clean_lib_path); strcat (linker_file_name_,"/linker"); execv (linker_file_name_,argv); error ("Can't execute the linker"); } r=wait_for_child (pid, "Linker",&status); if (!(r>=0 && status==0)) return 0; } # endif arg=argv; # ifdef USE_WLINK *arg++="wlink"; *arg++="sys"; *arg++="nt"; *arg++="op"; *arg++="c"; *arg++="op"; *arg++="q"; *arg++="op"; sprintf (stack_option,"stack=%dk",(ab_stack_size+1023) >> 10); *arg++=stack_option; # else # ifdef OMF *arg++="link386"; *arg++="/bat"; *arg++="/nol"; *arg++="/noe"; *arg++="/noi"; *arg++="/nod"; *arg++="/base:0x10000"; sprintf (stack_option,"/st:%ld",(long)ab_stack_size); *arg++=stack_option; # else # ifdef USE_CLEANLINKER *arg++="linker"; # else *arg++=linker_file_name; # endif # endif # endif { static char ld_args_copy[PATH_LIST_STRING_SIZE]; char *rest,*ld_arg; rest = strcpy (ld_args_copy,ld_args); while ((ld_arg=parse_word (&rest))!=NULL) *arg++=ld_arg; } # ifdef M68000 *arg++="-N"; # endif # if !defined (I486) && !MACINTOSH && !defined (SOLARIS) && !defined (LINUX) *arg++="-e"; *arg++="start"; *arg++="-dc"; *arg++="-dp"; # endif # if !MACINTOSH # if !(defined (USE_WLINK) || defined (OMF) || defined (USE_CLEANLINKER)) if (remove_symbol_table) *arg++="-s"; # endif # ifdef OS2 # ifndef OMF *arg++ = "-o"; l=strlen (application_file_name); if (l > 4 && strcmp (&application_file_name[l-4],".exe")==0) *arg++=application_file_name; else { strcpy (appl_file_name,application_file_name); strcat (appl_file_name,".exe"); *arg++=appl_file_name; } # endif # else if (application_file_name!=NULL){ # ifdef USE_WLINK *arg++="name"; # else *arg++="-o"; # endif *arg++=application_file_name; } # if defined (_WINDOWS_) && !defined (USE_CLEANLINKER) else { # ifdef USE_WLINK *arg++="name"; *arg++="a"; # else *arg++="-o"; *arg++="a.exe"; # endif } # endif # endif # if defined (OS2) && !defined (OMF) *arg++=gcc_lib_directory_arg; # endif # ifndef NO_CLIB # ifdef USE_WLINK *arg++="file"; strcpy (w_crt0_file_name,clean_lib_path); strcat (w_crt0_file_name,"\\crt0.obj"); *arg++=w_crt0_file_name; # else # ifdef OMF *arg++="e:\\emx\\lib\\crt0.obj"; # else # ifndef LINUX # ifdef SOLARIS need_file ("_startup",OBJECT_FILE_EXTENSION,start_up_file_name); strcpy (crt,start_up_file_name); replace_file_name_in_path (crt,"crt",OBJECT_FILE_EXTENSION); *arg++=crt; strcpy (crti,start_up_file_name); replace_file_name_in_path (crti,"crti",OBJECT_FILE_EXTENSION); *arg++=crti; # else *arg++=crt0_file_name; # endif # endif # endif # endif # endif # ifdef M68000 *arg++=Mcrt1_file_name; # endif # endif # ifdef OPTIMISE_LINK *arg++ = linker_output_object_file_name; # else # if (defined (_WINDOWS_) && !defined (USE_WLINK)) || defined (OMF) # ifdef NO_CLIB strcpy (startup0_file_name,clean_lib_path); strcat (startup0_file_name,"\\_startup0" OBJECT_FILE_EXTENSION); *arg++=startup0_file_name; # endif # ifdef OS2 { P_NODE project_node; for_l (project_node,first_project_node,pro_next) if (!strcmp (project_node->pro_fname,"_startup1")) break; if (project_node==NULL){ # endif strcpy (startup1_file_name,clean_lib_path); strcat (startup1_file_name,"\\_startup1" OBJECT_FILE_EXTENSION); *arg++=startup1_file_name; # ifdef OS2 } } { P_NODE project_node; for_l (project_node,first_project_node,pro_next) if (!strcmp (project_node->pro_fname,"_startup2")) break; if (project_node==NULL){ # endif strcpy (startup2_file_name,clean_lib_path); strcat (startup2_file_name,"\\_startup2" OBJECT_FILE_EXTENSION); *arg++=startup2_file_name; # ifdef OS2 } } # endif # else # if !(!defined (LINUX) && defined (SOLARIS)) need_file ("_startup",OBJECT_FILE_EXTENSION,start_up_file_name); # endif *arg++=start_up_file_name; # endif # ifdef OS2 { P_NODE project_node; for_l (project_node,first_project_node,pro_next) if (!strcmp (project_node->pro_fname,"_system")) break; if (project_node==NULL){ # endif need_file ("_system",OBJECT_FILE_EXTENSION,system_file_name); *arg++=system_file_name; # ifdef OS2 } } # endif for_l (project_node,first_project_node,pro_next){ if (project_node->pro_up_to_date && !project_node->pro_ignore_o){ char *file_name; # ifdef _WINDOWS_ FileTime time; # endif # if ! MACINTOSH if (!find_clean_system_file (project_node->pro_fname,OBJECT_FILE_EXTENSION,o_file_name, clean_o_path!=NULL ? clean_o_path : clean_abc_path # ifdef _WINDOWS_ ,&time # endif )) { error_s ("Can't find %s.o",project_node->pro_fname); } # else if (!find_clean_system_file (project_node->pro_fname,OBJECT_FILE_EXTENSION,o_file_name)) error_s ("Can't find %s" OBJECT_FILE_EXTENSION,project_node->pro_fname); # endif file_name=memory_allocate (strlen (o_file_name)+1); strcpy (file_name,o_file_name); # ifdef USE_WLINK *arg++="file"; # endif *arg++=file_name; } } # endif #ifndef OS2 for_l (library,first_library,library_next){ # ifdef OPTIMISE_LINK int s; if (library->library_file_name[0]==':') *arg++=&library->library_file_name[1]; else if (s=strlen (library->library_file_name), ! (s>=2 && library->library_file_name[s-2]=='.' && library->library_file_name[s-1]=='o')) # endif *arg++=library->library_file_name; } #endif # if MACINTOSH # if 1 { char library_obj_file_name[PATH_NAME_STRING_SIZE]; strcpy (library_obj_file_name,clean_lib_path); strcat (library_obj_file_name,":Clean System Files:_library" OBJECT_FILE_EXTENSION); *arg++=library_obj_file_name; *arg=NULL; return link_application_argc_argv (arg-argv,argv)==0; } # else { char **argument; if (application_file_name!=NULL) printf ("linker %s ",application_file_name); else printf ("linker a.out"); for (argument=argv; argument!=arg; ++argument) printf ("[partial]\n \'%s\'",*argument); printf ("[partial]\n \'%s:Clean System Files:_library.obj2\'\n",clean_lib_path); return 1; } # endif # else # if defined (OS2) && !defined (OMF) if (window_application){ strcpy (clean_resources_file_name,clean_lib_path); strcat (clean_resources_file_name,"\\clean.res"); *arg++ = clean_resources_file_name; strcpy (clean_def_file_name,clean_lib_path); strcat (clean_def_file_name,"\\clean.def"); *arg++ = clean_def_file_name; strcpy (os2_interface_file_name,clean_lib_path); strcat (os2_interface_file_name,"\\os2interface.lib"); *arg++ = os2_interface_file_name; } # endif # ifdef USE_WLINK *arg++="file"; # endif *arg++=options_file_name; # ifdef sparc strcpy (reals_file_name,start_up_file_name);\ replace_file_name_in_path (reals_file_name,"_reals",OBJECT_FILE_EXTENSION); *arg++=reals_file_name; # endif # if defined(_WINDOWS_) && !defined (USE_WLINK) && !defined (USE_CLEANLINKER) *arg++="-Lc:\\Gnu\\lib"; # endif # if defined (sparc) || (defined (I486) || defined (LINUX) && !defined (USE_WLINK) && !defined (OMF) && !defined (USE_CLEANLINKER)) *arg++="-lm"; # endif # ifdef OS2 # ifdef OMF *arg++=","; *arg++=application_file_name; *arg++=","; *arg++=","; # ifndef NO_CLIB *arg++="e:\\emx\\lib\\gcc.lib"; *arg++="e:\\emx\\lib\\st\\c.lib"; *arg++="e:\\emx\\lib\\st\\c_app.lib"; *arg++="e:\\emx\\lib\\st\\sys.lib"; # endif # ifdef OS2 for_l (library,first_library,library_next) *arg++=library->library_file_name; # endif # ifdef NO_CLIB strcpy (os2lib_file_name,clean_lib_path); strcat (os2lib_file_name,"\\os2.lib"); *arg++=os2lib_file_name; # else *arg++="e:\\emx\\lib\\os2.lib"; # endif *arg++=","; strcpy (clean_def_file_name,clean_lib_path); if (!window_application) strcat (clean_def_file_name,"\\text.def"); else strcat (clean_def_file_name,"\\clean.def"); *arg++ = clean_def_file_name; *arg++=","; # else *arg++="-lgcc"; *arg++="-lst/c"; *arg++="-lst/c_app"; *arg++="-lst/c_import"; *arg++="-lst/emx"; *arg++="-lemx2"; *arg++="-los2"; # endif # else # ifndef USE_WLINK # if defined (_WINDOWS_) && !defined (USE_WLINK) # ifndef NO_CLIB *arg++="-lgcc"; *arg++="-lc"; # endif # if defined (USE_CLEANLINKER) strcpy (kernel32_file_name,"-l"); strcat (kernel32_file_name,clean_lib_path); strcat (kernel32_file_name,"\\kernel_library"); *arg++ = kernel32_file_name; strcpy (user32_file_name,"-l"); strcat (user32_file_name,clean_lib_path); strcat (user32_file_name,"\\user_library"); *arg++ = user32_file_name; strcpy (gdi32_file_name,"-l"); strcat (gdi32_file_name,clean_lib_path); strcat (gdi32_file_name,"\\gdi_library"); *arg++ = gdi32_file_name; # else *arg++="-lkernel32"; # endif # ifndef NO_CLIB *arg++="-ladvapi32"; *arg++="-luser32"; *arg++="-lgcc"; # endif # else *arg++="-lc"; # ifdef SOLARIS strcpy (crtn,start_up_file_name); replace_file_name_in_path (crtn,"crtn",OBJECT_FILE_EXTENSION); *arg++=crtn; # endif # endif # endif # endif *arg=NULL; # if defined (OS2) || defined (_WINDOWS_) { int r; # ifdef _WINDOWS_ # ifdef GNU_C { int status; argv[0]=linker_file_name; r=spawnvp (P_WAIT,linker_file_name,argv); if (r>=0) r=wait (&status); return r>=0 && status==0; } # else r=spawnvp (P_WAIT,linker_file_name,argv); # endif # else r=dos_exec (linker_file_name,argv,1); # endif return r==0; } # else { int pid,r,status; pid=fork(); if (pid<0) error ("Fork failed"); if (!pid){ execv (linker_file_name,argv); error ("Can't execute the linker"); } r=wait_for_child (pid, "Linker",&status); # ifdef OPTIMISE_LINK unlink (linker_output_object_file_name); # endif return r>=0 && status==0; } # endif # endif } #endif static void print_version (void) { printf ( "Clean Compiler 1.2.6/0.%03d/1.2\n" "Copyright (C) 1987-1997 University of Nijmegen and HILT - High Level Software Tools B.V.\n" ,VERSION ); } #if defined (MAKE_MPW_TOOL) && defined (NB) static void print_help (void) { print_version(); printf ( "\n" "Clean [option...] file [option...]\n" " \"file\" is the name of the top-level .icl file\n" " -i directory[,directory...] # Search for imports in the named directories\n" " # in addition to the directory in which \"file\" resides\n" " -o directory # Look for and place all .abc and .objN files in directory\n" " -p # Write progress information to diagnostic\n" " -mc68020 # Generate code for mc68020 (w/o 68881) instead of mc68000\n" " -checkstack # Generate stack overflow checks\n" " -checkindices # Check array indices\n" " -funcmayfail # Function may fail is error\n" " -varnotused # Variable not used is error\n" " -funcnotused # Function not used is error\n" " -help # Print out usage information\n" " -h # Same as -help\n" " -nowarn # Suppress warnings\n" " -mv # Make verbose\n" " -ms # Make silent\n" " -O # Only make .objN file for main module\n" " -ABC # Only make .abc file for main module\n" " -PABC # Only make .abc files for project\n" ); } #endif static void print_version_and_variables (void) { fprintf (stderr, "clm - Clean make (version %s)\n", CLM_VERSION); #if defined (I486) && defined (DOS) fprintf (stderr,"\tclean_lib_directory = \n\t\t%s\n", clean_lib_directory); fprintf (stderr,"\tassembler_file_name =\n\t\t%s\n", assembler_file_name); fprintf (stderr,"\tlinker_file_name =\n\t\t%s\n", linker_file_name); fprintf (stderr,"\tcrt0_file_name =\n\t\t%s\n", crt0_file_name); fprintf (stderr,"\tgcc_lib_directory_arg =\n\t\t%s\n", gcc_lib_directory_arg); #else fprintf (stderr,"\tclean_lib_directory =\n\t\t%s\n", clean_lib_directory); fprintf (stderr,"\tclean_default_path_list =\n\t\t%s\n", clean_directory_list); fprintf (stderr,"\tassembler_file_name =\n\t\t%s\n", assembler_file_name); fprintf (stderr,"\tlinker_file_name =\n\t\t%s\n", linker_file_name); fprintf (stderr,"\tcrt0_file_name =\n\t\t%s\n", crt0_file_name); fprintf (stderr,"\tld_args =\n\t\t%s\n", ld_args); #endif #ifdef M68000 fprintf (stderr, "\tMcrt1_file_name =\n\t\t%s\n", Mcrt1_file_namee); #endif } static void argument_error (void) { #if defined (MAKE_MPW_TOOL) && defined (NB) print_help(); #else printf ("Usage: clm [options] module_name [-o application_name]\n"); printf ("project options: -mv -ms -O -S -ABC -PO -PS -PABC -c -lt -lat -ns -lset\n"); printf ("application options: -h size -s size -b -sc -t -nt -gc -ngc -st -nst -nr\n"); #ifdef MARKING_GC printf ("application options: -gcm -gcc -gcf int -gci size\n"); #endif printf ("main module options: -w -d -sa -v -nw -nd -nsa -nv\n"); #endif exit (1); } static long parse_size (register char *s) { register int c; register long n; c=*s++; if (c<'0' || c>'9') error ("Digit expected in argument\n"); n=c-'0'; while (c=*s++,c>='0' && c<='9') n=n*10+(c-'0'); if (c=='k' || c=='K'){ c=*s++; n<<=10; } else if (c=='m' || c=='M'){ c=*s++; n<<=20; } if (c!='\0') error ("Error in size"); return n; } #ifdef MARKING_GC static long parse_integer (register char *s) { register int c; register long n; c=*s++; if (c<'0' || c>'9') error ("Digit expected in argument\n"); n=c-'0'; while (c=*s++,c>='0' && c<='9') n=n*10+(c-'0'); if (c!='\0') error ("Error in integer"); return n; } #endif static void add_library (char *library_file_name) { int file_name_length; struct library_list *new_library_file; file_name_length=strlen (library_file_name); new_library_file=memory_allocate (sizeof (struct library_list)+file_name_length+1); strcpy (new_library_file->library_file_name,library_file_name); new_library_file->library_next=NULL; if (first_library==NULL) first_library=new_library_file; else last_library->library_next=new_library_file; last_library=new_library_file; } static P_NODE add_ignored (char *ignored_name) { P_NODE ignored_module; for_l (ignored_module,first_project_node,pro_next) if (!strcmp (ignored_name,ignored_module->pro_fname)) break; if (ignored_module==NULL) ignored_module=add_project_node(ignored_name); ignored_module->pro_ignore_o=1; return ignored_module; } static void read_shared_library (char *shared_script_name) { char script_file_name[PATH_NAME_STRING_SIZE]; char file_name[PATH_NAME_STRING_SIZE]; FILE *fp; #ifdef _WINDOWS_ FileTime time; #endif #if MACINTOSH if (!find_file (shared_script_name,".lo",script_file_name)) #else if (!find_file (shared_script_name,".lo",script_file_name,clean_lib_path # ifdef _WINDOWS_ ,&time # endif )) #endif error_s ("Can't find %s.lo",shared_script_name); if (!(fp=fopen (script_file_name,"r"))) error_s ("Can't open %s.lo",shared_script_name); while (fgets (file_name,PATH_NAME_STRING_SIZE,fp)!=NULL && file_name[0]!='='){ char *rest,*parsed_file_name; rest=file_name; while ((parsed_file_name=parse_word (&rest))!=NULL) add_library (parsed_file_name); } { P_NODE ignored_module; int adding_dependencies; ignored_module=NULL; adding_dependencies=0; while (fgets (file_name,PATH_NAME_STRING_SIZE,fp)!=NULL){ char *rest,*parsed_file_name; rest=file_name; while ((parsed_file_name=parse_word (&rest))!=NULL){ if (parsed_file_name[0]=='('){ ++parsed_file_name; adding_dependencies=1; } if (adding_dependencies){ int length; length=strlen (parsed_file_name); if (parsed_file_name[length-1]==')'){ --length; parsed_file_name[length]='\0'; adding_dependencies=0; } if (length>0){ if (ignored_module==NULL) fprintf (stderr,"no ignored module specified for %s\n",parsed_file_name); else add_dependency (&ignored_module->pro_depend,parsed_file_name); } } else ignored_module=add_ignored (file_name); } } } } #define option_on(mask) clean_options|=(mask); clean_options_mask|=(mask); #define option_off(mask) clean_options&=~(mask); clean_options_mask|=(mask); #ifdef __MWERKS__ # include extern int ccommand(char ***); # include #endif #ifdef applec # include #endif #if defined (OS2) && defined (OMF) static int add_resource_to_application (char *application_file_name) { char *argv[8],**arg; char clean_resources_file_name[PATH_NAME_STRING_SIZE]; int r; strcpy (clean_resources_file_name,clean_lib_path); strcat (clean_resources_file_name,"\\clean.res"); arg=argv; *arg++="rc.exe"; *arg++=clean_resources_file_name; *arg++=application_file_name; *arg=NULL; r=dos_exec ("rc.exe",argv,0); return r==0; } #endif #if defined (__MWERKS__) && !defined (MAKE_MPW_TOOL) int main (void) { int argc; char *(arg_vector[32]),**argv; #else int main (int argc,char **argv) { #endif int arg_n; char *application_file_name,*main_module_name; #if MACINTOSH || defined (POWER) # if defined (__MWERKS__) && !defined (MAKE_MPW_TOOL) SetApplLimit (GetApplLimit() - 200*1024); argv=arg_vector; argc = ccommand (&argv); # else # ifdef applec SetApplLimit (GetApplLimit() - 200*1024); # endif # ifdef _LBFSIZ setvbuf (stdout,NULL,_IOLBF,_LBFSIZ); # else setvbuf (stdout,NULL,_IOLBF,256); # endif # endif #endif #if defined (__MWERKS__) && !defined (MAKE_MPW_TOOL) SIOUXSettings.showstatusline=0; #endif #ifdef OS2 clm_file_name=argv[0]; #endif #if MACINTOSH && !defined (G_POWER) OBJECT_FILE_EXTENSION=".obj0"; #endif #ifdef DOS { int length; strcpy (clean_lib_directory,argv[0]); length=strlen (clean_lib_directory); while (length>0){ --length; if (clean_lib_directory[length]=='/' || clean_lib_directory[length]=='\\') { clean_lib_directory[length]=0; break; } } if (length==0) error ("argv[0] doesn't contain path name"); strcat (clean_lib_directory,"/lib"); } #endif if (argc==2 && strcmp (argv[1],"-V")==0){ print_version_and_variables(); exit (0); } if (argc<2 || argv[argc-1][0]=='-') argument_error(); heap_size=2048<<10; ab_stack_size=512<<10; flags=8; #ifdef MARKING_GC initial_heap_size=100<10; heap_size_multiple=20<<8; #endif remove_symbol_table=1; check_stack_overflow=0; check_indices=0; #ifdef OS2 window_application=0; #endif cocl_redirect_stdout=NULL; cocl_redirect_stderr=NULL; first_library=NULL; last_library=NULL; get_paths(); #if defined (MAKE_MPW_TOOL) && defined (NB) main_module_name=NULL; for (arg_n=1; arg_n=argc) error ("Heap size missing\n"); heap_size=parse_size (argv[arg_n]); } #endif else if (!strcmp (s,"s")){ ++arg_n; if (arg_n>=argc) error ("Stack size missing\n"); ab_stack_size=parse_size (argv[arg_n]); } else if (!strcmp (s,"b")) flags |= 1; else if (!strcmp (s,"sc")) flags &= ~1; else if (!strcmp (s,"t")) flags |= 8; else if (!strcmp (s,"nt")) flags &= ~8; else if (!strcmp (s,"gc")) flags |= 2; else if (!strcmp (s,"ngc")) flags &= ~2; else if (!strcmp (s,"st")) flags |= 4; else if (!strcmp (s,"nst")) flags &= ~4; else if (!strcmp (s,"nr")) flags |= 16; #ifdef MARKING_GC else if (!strcmp (s,"gcm")) flags |= 64; else if (!strcmp (s,"gcc")) flags &= ~64; else if (!strcmp (s,"gci")){ ++arg_n; if (arg_n>=argc) error ("Initial heap size missing\n"); initial_heap_size=parse_size (argv[arg_n]); } else if (!strcmp (s,"gcf")){ ++arg_n; if (arg_n>=argc) error ("Next heap size factor missing\n"); heap_size_multiple=parse_integer (argv[arg_n])<<8; } #endif /* clean options */ else if (!strcmp (s,"v")){ option_on (VERBOSE_MASK); } else if (!strcmp (s,"nv")){ option_off (VERBOSE_MASK); } else if (!strcmp (s,"w")){ option_on (WARNING_MASK); } else if (!strcmp (s,"nw")){ option_off (WARNING_MASK); } else if (!strcmp (s,"d")){ option_on (DEBUG_MASK); } else if (!strcmp (s,"nd")){ option_off (DEBUG_MASK); } else if (!strcmp (s,"sa")){ option_on (STRICTNESS_ANALYSIS_MASK); } else if (!strcmp (s,"nsa")){ option_off (STRICTNESS_ANALYSIS_MASK); } else if (!strcmp (s,"lt")){ option_on (LIST_TYPES_MASK); } else if (!strcmp (s,"nlt")){ option_off (LIST_TYPES_MASK); } else if (!strcmp (s,"lat")){ option_on (LIST_ALL_TYPES_MASK); } else if (!strcmp (s,"nlat")){ option_off (LIST_ALL_TYPES_MASK); } else if (!strcmp (s,"lset")){ list_strict_export_types=1; } else if (!strcmp (s,"ou")){ option_on (REUSE_UNIQUE_NODES); } else if (!strcmp (s,"nou")){ option_off (REUSE_UNIQUE_NODES); /* } else if (!strcmp (s,"pm")){ option_on (MEMORY_PROFILE); } else if (!strcmp (s,"npm")){ option_off (MEMORY_PROFILE); } else if (!strcmp (s,"pt")){ option_on (TIME_PROFILE); } else if (!strcmp (s,"npt")){ option_off (TIME_PROFILE); */ } else if (strcmp (s, "RE") == 0 || strcmp (s, "RAE") == 0){ cocl_redirect_stderr_option = argument; if (++arg_n < argc) cocl_redirect_stderr = argv [arg_n]; else error ("file name expected after -RE"); } else if (strcmp (s, "RO") == 0 || strcmp (s, "RAO") == 0){ cocl_redirect_stdout_option = argument; if (++arg_n < argc) cocl_redirect_stdout = argv [arg_n]; else error ("file name expected after -RO"); } else if (!strcmp (s,"funcmayfail")){ funcmayfail_error=1; } else if (!strcmp (s,"varnotused")){ varnotused_error=1; } else if (!strcmp (s,"funcnotused")){ funcnotused_error=1; } else if (!strcmp (s,"nowarn")){ nowarn=1; #ifndef OS2 } else if (!strcmp (s,"p")){ progress=1; #endif /* code generator options */ } else if (!strcmp (s,"ci")){ check_indices=1; #if defined (MAKE_MPW_TOOL) && defined (NB) } else if (!strcmp (s,"checkstack")){ check_stack_overflow=1; } else if (!strcmp (s,"checkindices")){ check_indices=1; } else if (!strcmp (s,"mc68020")){ generate_mc68020_code=1; OBJECT_FILE_EXTENSION=".obj1"; } else if (!strcmp (s,"h") || !strcmp (s,"help")){ show_help=1; #endif } else if (!strcmp (s,"l")){ ++arg_n; if (arg_n>=argc) error ("Library name missing\n"); add_library (argv[arg_n]); } else if (!strcmp (s,"sl")){ ++arg_n; if (arg_n>=argc) error ("Shared library name missing\n"); read_shared_library (argv[arg_n]); #ifdef OS2 } else if (!strcmp (s,"p")) { window_application=1; #endif } else if (!strcmp (s,"P")){ ++arg_n; if (arg_n>=argc) error ("Path list missing\n"); clean_path_list=argv[arg_n]; } else if (!strcmp (s,"I")){ ++arg_n; if (arg_n>=argc) error ("Path missing\n"); if (clean_path_list[0]!='\0') strcat (clean_path_list,":"); strcat (clean_path_list,argv[arg_n]); #if defined (MAKE_MPW_TOOL) && defined (NB) } else if (!strcmp (s,"o")){ ++arg_n; if (arg_n>=argc) error ("Output path missing\n"); clean_abc_path=clean_o_path=argv[arg_n]; #endif } else error_s ("Unknown option: %s",argument); } #if defined (MAKE_MPW_TOOL) && defined (NB) if (main_module_name==NULL) argument_error(); if (show_help) print_help(); { int l; l=strlen (main_module_name); if (l>4 && !strcmp (&main_module_name[l-4],".icl")){ main_module_name[l-4]='\0'; l-=4; } while (l>=0 && main_module_name[l]!=':') --l; if (l>=0){ main_module_path=memory_allocate (l+2); main_module_name[l]=0; strcpy (main_module_path,main_module_name); strcat (main_module_path,":"); main_module_name=&main_module_name[l+1]; } else main_module_path=NULL; } application_file_name=NULL; #else main_module_name=argv[arg_n]; if (arg_n==argc-3){ if (strcmp (argv[arg_n+1],"-o")!=0) argument_error(); application_file_name=argv[arg_n+2]; } else { # ifdef OS2 int length; length=strlen (main_module_name); application_file_name=memory_allocate (length+5); strcpy (application_file_name,main_module_name); strcat (application_file_name,".exe"); # else application_file_name=NULL; # endif if (arg_n!=argc-1) argument_error(); } #endif #if MACINTOSH initialise_path_list(); #endif if (progress) print_version(); if (first_project_node==NULL) main_project_node=add_project_node (main_module_name); else { P_NODE old_first_project_node,old_last_project_node; old_first_project_node=first_project_node; old_last_project_node=last_project_node; first_project_node=NULL; main_project_node=add_project_node (main_module_name); main_project_node->pro_next=old_first_project_node; last_project_node=old_last_project_node; } #ifdef NB { P_NODE _system_pnode; _system_pnode=add_project_node ("_system"); #endif if (make_project_to_abc_files (first_project_node) #ifdef NB && make_project_to_abc_files (_system_pnode) #endif ){ #ifdef CACHING_COMPILER if (compiler_started){ stop_compiler(); compiler_started=0; } #endif if (only_abc_files || syntax_check) return 0; if (only_s_files) return make_project_to_s_files(); if (make_project_to_o_files()){ #if ! MACINTOSH char *options_file_name; #endif if (only_o_files) return 0; #ifdef USE_TOOLSERVER if (!link_project_toolserver (first_project_node,NULL,application_file_name)) return 1; add_stack_and_size_resource_to_application (application_file_name); return 0; #else # ifndef MAKE_MPW_TOOL if (create_options_file (&options_file_name)){ if (!link_project (first_project_node,options_file_name,application_file_name)){ unlink (options_file_name); return 1; } unlink (options_file_name); # if defined (OS2) && defined (OMF) if (window_application && !add_resource_to_application (application_file_name)) return 1; # endif return 0; } # endif #endif } } #ifdef NB } #endif #ifdef CACHING_COMPILER stop_compiler (); #endif return 1; }