Patch title: Release 87 bulk changes
Abstract:
File: /pliant/language/startup/startup.c
Key:
    Removed line
    Added line
   
// Copyright  Hubert Tonneau  hubert.tonneau@pliant.cx
//
// This program is free software; you can redistribute it an
// modify it under the terms of the GNU General Public Licen
// as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be u
// but WITHOUT ANY WARRANTY; without even the implied warran
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public
// version 2 along with this program; if not, write to the F
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA


#ifdef _DLL_
  #ifdef _GCC_
    // ... is required in order to get around GCC bug
    // it should have rather been void _EXTERNAL_ pliant(int
    void pliant(int argc,char **args,char **env,int debuggin
  #else
    void _EXTERNAL_ pliant(int argc,char **args,char **env,i
  #endif
#else
  #ifdef _EXE_
    int _EXTERNAL_ main(int argc,char **args,char **env)
  #else
    void _EXTERNAL_ startup()
  #endif
#endif
{
  Int verbose_level,nb_methods_indices; Bool initialized;
  #if defined(_WIN32_API_) && !defined(_DLL_) && !defined(_E
    char *args[16]; int argc;
    char *cmdline,*src,*dest;
  #endif
  #if defined(_OS2_API_) && !defined(_DLL_) && !defined(_EXE
    char *args[16]; int argc;
    TIB *tib; PIB *pib; char *src,*dest;
  #endif
  #if defined(_LINUX_API_) || defined(_POSIX_API_)
    #if !defined(_DLL_) && !defined(_EXE_)
      #define args process_args
      #define argc process_argc
    #endif
  #endif
  Address base_address;
  Int decommit_threshold;
  #ifndef _DLL_
    int debugging_level;
    char *pliant_path;
    #ifdef _FIND_ROOT_PATH_
      char pliant_path_buffer[256];
    #endif
  #endif
  Int a,i; uInt u; char *ch,*stop; struct Str temp,temp2; Ch
  struct Str *line; struct List *text; struct Module *module
  struct Str precompile;
  Arrow *c; struct DelayedAction *ea;
  #ifdef _TIMER_
    Int old;
  #endif
  #if defined(_LINUX_API_) || defined(_POSIX_API_)
    #if defined(_DLL_) || defined(_EXE_)
      process_env=env;
      process_args=args;
    #endif
  #endif
  base_address=null;
  decommit_threshold=64*1024;
  verbose_level=1;
  nb_methods_indices=32;
  initialized=false;
  last_module=null;
  Str_map_string(&precompile,"");
  #if defined(_LINUX_API_) && !defined(_DLL_)
    for(argc=0; args[argc]!=null; argc++);
  #endif
  #if defined(_WIN32_API_) && !defined(_DLL_) && !defined(_E
    cmdline=GetCommandLine();
    argc=0;
    for(src=cmdline,dest=src; *src!='\0'; )
      if(*src=='\'') {
        if(dest==cmdline || dest[-1]=='\0') args[argc++]=des
        src++; while(*src!='\'' && *src!='\0') *dest++=*src+
        if(*src!='\0') src++;
      orif(*src==' ')
        *dest++='\0'; src++;
      other
        if(dest==cmdline || dest[-1]=='\0') args[argc++]=des
        *dest++=*src++; }
    *dest='\0'; args[argc]=0;
  #endif
  #if defined(_OS2_API_) && !defined(_DLL_) && !defined(_EXE
    DosGetInfoBlocks(&tib,&pib);
    args[0]=pib->pib_pchcmd; argc=1;
    for(src=pib->pib_pchcmd+string_len(pib->pib_pchcmd)+1,de
      if(*src=='\'') {
        if(dest[-1]=='\0') args[argc++]=dest;
        src++; while(*src!='\'' && *src!='\0') *dest++=*src+
        if(*src!='\0') src++;
      orif(*src==' ')
        *dest++='\0'; src++;
      other
        if(dest[-1]=='\0') args[argc++]=dest;
        *dest++=*src++; }
    *dest='\0'; args[argc]=0;
  #endif
  #ifndef _DLL_
    #ifdef _FIND_ROOT_PATH_
      pliant_path=find_root_path(pliant_path_buffer);
    #else
      pliant_path="/pliant/";
    #endif
    debugging_level=c_debugging_level;
  #endif
// Copyright  Hubert Tonneau  hubert.tonneau@pliant.cx
//
// This program is free software; you can redistribute it an
// modify it under the terms of the GNU General Public Licen
// as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be u
// but WITHOUT ANY WARRANTY; without even the implied warran
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public
// version 2 along with this program; if not, write to the F
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA


#ifdef _DLL_
  #ifdef _GCC_
    // ... is required in order to get around GCC bug
    // it should have rather been void _EXTERNAL_ pliant(int
    void pliant(int argc,char **args,char **env,int debuggin
  #else
    void _EXTERNAL_ pliant(int argc,char **args,char **env,i
  #endif
#else
  #ifdef _EXE_
    int _EXTERNAL_ main(int argc,char **args,char **env)
  #else
    void _EXTERNAL_ startup()
  #endif
#endif
{
  Int verbose_level,nb_methods_indices; Bool initialized;
  #if defined(_WIN32_API_) && !defined(_DLL_) && !defined(_E
    char *args[16]; int argc;
    char *cmdline,*src,*dest;
  #endif
  #if defined(_OS2_API_) && !defined(_DLL_) && !defined(_EXE
    char *args[16]; int argc;
    TIB *tib; PIB *pib; char *src,*dest;
  #endif
  #if defined(_LINUX_API_) || defined(_POSIX_API_)
    #if !defined(_DLL_) && !defined(_EXE_)
      #define args process_args
      #define argc process_argc
    #endif
  #endif
  Address base_address;
  Int decommit_threshold;
  #ifndef _DLL_
    int debugging_level;
    char *pliant_path;
    #ifdef _FIND_ROOT_PATH_
      char pliant_path_buffer[256];
    #endif
  #endif
  Int a,i; uInt u; char *ch,*stop; struct Str temp,temp2; Ch
  struct Str *line; struct List *text; struct Module *module
  struct Str precompile;
  Arrow *c; struct DelayedAction *ea;
  #ifdef _TIMER_
    Int old;
  #endif
  #if defined(_LINUX_API_) || defined(_POSIX_API_)
    #if defined(_DLL_) || defined(_EXE_)
      process_env=env;
      process_args=args;
    #endif
  #endif
  base_address=null;
  decommit_threshold=64*1024;
  verbose_level=1;
  nb_methods_indices=32;
  initialized=false;
  last_module=null;
  Str_map_string(&precompile,"");
  #if defined(_LINUX_API_) && !defined(_DLL_)
    for(argc=0; args[argc]!=null; argc++);
  #endif
  #if defined(_WIN32_API_) && !defined(_DLL_) && !defined(_E
    cmdline=GetCommandLine();
    argc=0;
    for(src=cmdline,dest=src; *src!='\0'; )
      if(*src=='\'') {
        if(dest==cmdline || dest[-1]=='\0') args[argc++]=des
        src++; while(*src!='\'' && *src!='\0') *dest++=*src+
        if(*src!='\0') src++;
      orif(*src==' ')
        *dest++='\0'; src++;
      other
        if(dest==cmdline || dest[-1]=='\0') args[argc++]=des
        *dest++=*src++; }
    *dest='\0'; args[argc]=0;
  #endif
  #if defined(_OS2_API_) && !defined(_DLL_) && !defined(_EXE
    DosGetInfoBlocks(&tib,&pib);
    args[0]=pib->pib_pchcmd; argc=1;
    for(src=pib->pib_pchcmd+string_len(pib->pib_pchcmd)+1,de
      if(*src=='\'') {
        if(dest[-1]=='\0') args[argc++]=dest;
        src++; while(*src!='\'' && *src!='\0') *dest++=*src+
        if(*src!='\0') src++;
      orif(*src==' ')
        *dest++='\0'; src++;
      other
        if(dest[-1]=='\0') args[argc++]=dest;
        *dest++=*src++; }
    *dest='\0'; args[argc]=0;
  #endif
  #ifndef _DLL_
    #ifdef _FIND_ROOT_PATH_
      pliant_path=find_root_path(pliant_path_buffer);
    #else
      pliant_path="/pliant/";
    #endif
    debugging_level=c_debugging_level;
  #endif

  #if defined(_WIN32_API_) || defined(_OS2_API_)
    for(ch=args[0]; *ch!='\0'; ch++) {
      if(*ch=='\\') *ch='/';
      if(*ch=='.') *ch='\0';
      if(*ch>='A' && *ch<='Z') *ch+='a'-'A'; }
  #else
    for(ch=args[0]; *ch!='\0'; ch++);
  #endif
  while(ch!=args[0] && ch[-1]!='/') ch--;
  if(equal(ch,"fullpliant")) {
    if(!process_restore(debugging_level,pliant_path,Str_map_string(&precompile,"/binary/default.dump"))) {
      initialize(debugging_level,verbose_level,base_address,decommit_threshold,pliant_path,nb_methods_indices,false);
      load_module(Str_map_string(&temp,"/pliant/install/precompile.pli"),G.safe_module,0,null);
      error_report();
      process_backup(&precompile);
      Str_map_string(&precompile,""); }
    initialized=true;
    load_module(Str_map_string(&temp,"/pliant/fullpliant/run.pli"),G.safe_module,0,null);
    error_report();
  orif(equal(ch,"recover"))
    initialize(debugging_level,verbose_level,base_address,decommit_threshold,pliant_path,nb_methods_indices,false);
    initialized=true;
    load_module(Str_map_string(&temp,"/pliant/install/recover.pli"),G.safe_module,0,null);
    error_report(); }

  for(a=1; a<argc; a++) { /// section "parse"
    ch=args[a];


FUNCTION Void do_nothing() {}
  for(a=1; a<argc; a++) { /// section "parse"
    ch=args[a];


FUNCTION Void do_nothing() {}
#define TERMINATE(msg) // consolen(Z,msg,END)
#define TERMINATE(msg) consolen(Z,msg,END)


    List_destroy(G.execute_begin_hooks); List_build(G.execut
    List_destroy(G.execute_end_hooks); List_build(G.execute_
    Arrow_set(&G.bottom_error.context,null);
    for(h=G.entry_first; h!=null; h=h->next)
      if(h->type==G.type_Type)
        entry_lock(h+1);
    entry_lock(G.general_dictionary);
    for(h=G.entry_first; h!=null; h=h->next)
      h->index=int_bad;
    for(i=0; i<G.general_dictionary->hashsize; i++)
      for(n=G.general_dictionary->table[i]; n!=null; n=n->ne
        h=(struct EntryHeader *)n->object-1;
        h->index=i; }
    for(h=G.entry_last,entry_lock(h+1); h!=null; h=h2) {
      if(h->index>=0)
        for(l=G.general_dictionary->table+h->index; (n=*l)!=
          if(n->object==h+1) {
            *l=n->next;
            entry_unlock(n->object);
            Str_destroy(&n->label);
            memory_free(n);
            G.general_dictionary->count--;
            break; }
      h2=h->previous; if(h2!=null) entry_lock(h2+1); entry_u
    entry_unlock(G.general_dictionary);
    TERMINATE("3");
    G.execution_phase=phase_free_types;
    for(h=G.entry_first; h!=null; h=h->next)
      if(h->type==G.type_Type) {
              t=(struct Type *)(h+1);
        for(i=0; i<G.generic_nb_indices; i++)
          if(i!=G.generic_method_destroy)
            Arrow_set((Arrow *)&t->generic_methods[i].functi
        List_destroy(&t->maybe); List_build(&t->maybe);
        for(i=0; i<t->nb_field; i++)
          Arrow_set(&t->fields[i].initial_value,null); }
    TERMINATE("4");
    while(List_last(&G.entry_roots)!=G.null_constant)
      List_remove(&G.entry_roots,List_last(&G.entry_roots));
    List_destroy(&G.entry_roots);
    TERMINATE("5");
    Str_destroy(&G.pliant_root_path);
    Str_destroy(&G.bottom_error.message);
    for(i=0; i<G.generic_nb_indices; i++)
      List_destroy(&G.generic_indices[i].types);
    memory_free(G.generic_indices);
    #ifdef _LISTING_
      Str_destroy(&G.initial_listing_function_name);
      Str_destroy(&G.expanded_listing_function_name);
      Str_destroy(&G.middle_listing_function_name);
      Str_destroy(&G.final_listing_function_name);
    #endif
    TERMINATE("6");
    for(h=G.entry_last,entry_lock(h+1); h!=null; h=h2) {
      if(h->type==G.type_Type) {


    List_destroy(G.execute_begin_hooks); List_build(G.execut
    List_destroy(G.execute_end_hooks); List_build(G.execute_
    Arrow_set(&G.bottom_error.context,null);
    for(h=G.entry_first; h!=null; h=h->next)
      if(h->type==G.type_Type)
        entry_lock(h+1);
    entry_lock(G.general_dictionary);
    for(h=G.entry_first; h!=null; h=h->next)
      h->index=int_bad;
    for(i=0; i<G.general_dictionary->hashsize; i++)
      for(n=G.general_dictionary->table[i]; n!=null; n=n->ne
        h=(struct EntryHeader *)n->object-1;
        h->index=i; }
    for(h=G.entry_last,entry_lock(h+1); h!=null; h=h2) {
      if(h->index>=0)
        for(l=G.general_dictionary->table+h->index; (n=*l)!=
          if(n->object==h+1) {
            *l=n->next;
            entry_unlock(n->object);
            Str_destroy(&n->label);
            memory_free(n);
            G.general_dictionary->count--;
            break; }
      h2=h->previous; if(h2!=null) entry_lock(h2+1); entry_u
    entry_unlock(G.general_dictionary);
    TERMINATE("3");
    G.execution_phase=phase_free_types;
    for(h=G.entry_first; h!=null; h=h->next)
      if(h->type==G.type_Type) {
              t=(struct Type *)(h+1);
        for(i=0; i<G.generic_nb_indices; i++)
          if(i!=G.generic_method_destroy)
            Arrow_set((Arrow *)&t->generic_methods[i].functi
        List_destroy(&t->maybe); List_build(&t->maybe);
        for(i=0; i<t->nb_field; i++)
          Arrow_set(&t->fields[i].initial_value,null); }
    TERMINATE("4");
    while(List_last(&G.entry_roots)!=G.null_constant)
      List_remove(&G.entry_roots,List_last(&G.entry_roots));
    List_destroy(&G.entry_roots);
    TERMINATE("5");
    Str_destroy(&G.pliant_root_path);
    Str_destroy(&G.bottom_error.message);
    for(i=0; i<G.generic_nb_indices; i++)
      List_destroy(&G.generic_indices[i].types);
    memory_free(G.generic_indices);
    #ifdef _LISTING_
      Str_destroy(&G.initial_listing_function_name);
      Str_destroy(&G.expanded_listing_function_name);
      Str_destroy(&G.middle_listing_function_name);
      Str_destroy(&G.final_listing_function_name);
    #endif
    TERMINATE("6");
    for(h=G.entry_last,entry_lock(h+1); h!=null; h=h2) {
      if(h->type==G.type_Type) {
              t=(struct Type *)(h+1);
        t=(struct Type *)(h+1);
        Arrow_set((Arrow *)&t->generic_methods[G.generic_met
        if(t!=G.type_Type && t!=G.type_Function)
          entry_unlock(t); }
      h2=h->previous; if(h2!=null) entry_lock(h2+1); entry_u
    TERMINATE("7");
    if(entry_header(G.type_Function)->counter==1) {
      entry_unrecord(entry_header(G.type_Function)); Type_de
    if(entry_header(G.type_Type)->counter==1) {
      entry_unrecord(entry_header(G.type_Type)); Type_destro
        Arrow_set((Arrow *)&t->generic_methods[G.generic_met
        if(t!=G.type_Type && t!=G.type_Function)
          entry_unlock(t); }
      h2=h->previous; if(h2!=null) entry_lock(h2+1); entry_u
    TERMINATE("7");
    if(entry_header(G.type_Function)->counter==1) {
      entry_unrecord(entry_header(G.type_Function)); Type_de
    if(entry_header(G.type_Type)->counter==1) {
      entry_unrecord(entry_header(G.type_Type)); Type_destro
    TERMINATE("8)\n");
    TERMINATE("8)\r                                \r");
    if(G.memory_current_used!=0) {
      G.execution_phase=phase_free_report;
      consolen(Z,"\n----------------------------------------
      if(G.entry_first!=null) {
        for(h=G.entry_first,i=0,j=0; h!=null; h=h->next,i++)
          j+=h->counter;
        consolen(
          S,Str_map_area(&temp,buffer,Int_str2(i,10,buffer))
          Z," object(s) have not been freed because of at mo
          S,Str_map_area(&temp2,buffer2,Int_str2(j,10,buffer
          Z," lost link(s).",EOL); }
      consolen(
        S,Str_map_area(&temp,buffer,Int_str2(G.memory_curren
        Z," byte(s) have not been freed\n",
        Z,"-----------------------------------------",EOL);
      for(h=G.entry_first; h!=null; h=h->next) {
        t=h->type; if(t->signature!=Type_signature || t->obj
        consolen(
          S,Str_map_area(&temp,buffer,Int_str2(t->objects_co
          Z," object(s) with type ",
          S,&t->name,
          EOL);
        t->objects_counter=0; }
      if(G.memory_current_used<4096) {
        consolen(Z,"----------------------------------------
        memory_dump(); }
      consolen(Z,"-----------------------------------------"
#endif


    if(G.memory_current_used!=0) {
      G.execution_phase=phase_free_report;
      consolen(Z,"\n----------------------------------------
      if(G.entry_first!=null) {
        for(h=G.entry_first,i=0,j=0; h!=null; h=h->next,i++)
          j+=h->counter;
        consolen(
          S,Str_map_area(&temp,buffer,Int_str2(i,10,buffer))
          Z," object(s) have not been freed because of at mo
          S,Str_map_area(&temp2,buffer2,Int_str2(j,10,buffer
          Z," lost link(s).",EOL); }
      consolen(
        S,Str_map_area(&temp,buffer,Int_str2(G.memory_curren
        Z," byte(s) have not been freed\n",
        Z,"-----------------------------------------",EOL);
      for(h=G.entry_first; h!=null; h=h->next) {
        t=h->type; if(t->signature!=Type_signature || t->obj
        consolen(
          S,Str_map_area(&temp,buffer,Int_str2(t->objects_co
          Z," object(s) with type ",
          S,&t->name,
          EOL);
        t->objects_counter=0; }
      if(G.memory_current_used<4096) {
        consolen(Z,"----------------------------------------
        memory_dump(); }
      consolen(Z,"-----------------------------------------"
#endif