From 2acdd3c782eee9ecfdee425c6fa1ebbaf099bf90 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 29 Oct 1995 23:24:06 +0100
Subject: [PATCH] fixed bugs

Rev: src/language.y:1.2
Rev: src/las.h:1.2
Rev: src/lex.c:1.2
Rev: src/modules/files/file.c:1.2
Rev: src/program.c:1.2
---
 src/language.y           | 96 +++++++++++++++++++---------------------
 src/las.h                |  1 +
 src/lex.c                | 27 ++---------
 src/modules/files/file.c | 56 +++++++++++++----------
 src/program.c            | 95 ++++++++++++++++++++++++++++++---------
 5 files changed, 155 insertions(+), 120 deletions(-)

diff --git a/src/language.y b/src/language.y
index a9b2031bf2..9d0cbc9fae 100644
--- a/src/language.y
+++ b/src/language.y
@@ -221,7 +221,7 @@ void fix_comp_stack(int sp)
 %type <n> lambda for_expr block  assoc_pair new_local_name
 %type <n> expr_list2 m_expr_list m_expr_list2 statement gauge sscanf
 %type <n> for do cond optional_else_part while statements
-%type <n> local_name_list
+%type <n> local_name_list class
 %type <n> unused2 foreach unused switch case return expr_list default
 %type <n> continue break block_or_semi
 %%
@@ -336,7 +336,7 @@ def: modifiers type_or_error optional_stars F_IDENTIFIER '(' arguments ')'
        }else{
 	 vargs=0;
        }
-       ins_byte(local_variables->current_number_of_locals, A_PROGRAM);
+       ins_byte(local_variables->max_number_of_locals, A_PROGRAM);
        ins_byte(args, A_PROGRAM);
        dooptcode($4, $9, $6);
 
@@ -571,18 +571,15 @@ block:'{'
      {
        $<number>$=local_variables->current_number_of_locals;
      } 
-     statements '}'
+     statements
+     '}'
      {
-       int e;
-       for(e=($<number>2)+1;e<local_variables->current_number_of_locals;e++)
+       while(local_variables->current_number_of_locals > $<number>2)
        {
-	 if(local_variables->variable[e].name)
-	 {
-	   free_string(local_variables->variable[e].name);
-	   free_string(local_variables->variable[e].type);
-	 }
-	 local_variables->variable[e].name=0;
-	 local_variables->variable[e].type=0;
+	 int e;
+	 e=--(local_variables->current_number_of_locals);
+	 free_string(local_variables->variable[e].name);
+	 free_string(local_variables->variable[e].type);
        }
        $$=$3;
      } ;
@@ -677,7 +674,7 @@ lambda: F_LAMBDA
 	  }else{
 	    vargs=0;
 	  }
-	  ins_byte(local_variables->current_number_of_locals, A_PROGRAM);
+	  ins_byte(local_variables->max_number_of_locals, A_PROGRAM);
 	  ins_byte(args, A_PROGRAM);
 	  
 	  sprintf(buf,"__lambda_%ld",
@@ -695,6 +692,27 @@ lambda: F_LAMBDA
           $$=mkidentifiernode(f);
 	} ;
 
+class: F_CLASS '{'
+       {
+         start_new_program();
+       }
+       program
+       '}'
+       {
+         struct svalue s;
+         s.u.program=end_program();
+	 if(!s.u.program)
+	 {
+	   yyerror("Class definition failed.");
+           s.type=T_INT;
+           s.subtype=0;
+	 } else {
+           s.type=T_PROGRAM;
+           s.subtype=0;
+         }
+	 $$=mksvaluenode(&s);
+         free(&s);
+       } ;
 
 cond: F_IF '(' comma_expr ')' 
       statement
@@ -903,6 +921,7 @@ expr4: string
      | gauge
      | sscanf
      | lambda
+     | class
      | F_IDENTIFIER
      {
        int i;
@@ -960,11 +979,15 @@ expr4: string
        f=reference_inherited_identifier($1,$3);
        idp=fake_program.identifier_references+f;
        if (f<0 || ID_FROM_PTR(&fake_program,idp)->func.offset == -1)
+       {
 	 my_yyerror("Undefined identifier %s::%s", $1->str,$3->str);
+	 $$=mkintnode(0);
+       } else {
+	 $$=mkidentifiernode(f);
+       }
 
        free_string($1);
        free_string($3);
-       $$=mkidentifiernode(f);
      }
      | F_COLON_COLON F_IDENTIFIER
      {
@@ -1080,6 +1103,12 @@ void add_local_name(struct lpc_string *str,
     local_variables->variable[local_variables->current_number_of_locals].type = type;
     local_variables->variable[local_variables->current_number_of_locals].name = str;
     local_variables->current_number_of_locals++;
+    if(local_variables->current_number_of_locals > 
+       local_variables->max_number_of_locals)
+    {
+      local_variables->max_number_of_locals=
+	local_variables->current_number_of_locals;
+    }
   }
 }
 
@@ -1110,42 +1139,6 @@ void free_all_local_names()
   local_variables->current_number_of_locals = 0;
 }
 
-
-#ifdef DEBUG
-void dump_program_desc(struct program *p)
-{
-  int e,d,q;
-/*  fprintf(stderr,"Program '%s':\n",p->name->str); */
-
-/*
-  fprintf(stderr,"All inherits:\n");
-  for(e=0;e<p->num_inherits;e++)
-  {
-    fprintf(stderr,"%3d:",e);
-    for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr,"  ");
-    fprintf(stderr,"%s\n",p->inherits[e].prog->name->str);
-  }
-*/
-
-  fprintf(stderr,"All identifiers:\n");
-  for(e=0;e<(int)p->num_identifier_references;e++)
-  {
-    fprintf(stderr,"%3d:",e);
-    for(d=0;d<INHERIT_FROM_INT(p,e)->inherit_level;d++) fprintf(stderr,"  ");
-    fprintf(stderr,"%s;\n",ID_FROM_INT(p,e)->name->str);
-  }
-  fprintf(stderr,"All sorted identifiers:\n");
-  for(q=0;q<(int)p->num_identifier_indexes;q++)
-  {
-    e=p->identifier_index[q];
-    fprintf(stderr,"%3d (%3d):",e,q);
-    for(d=0;d<INHERIT_FROM_INT(p,e)->inherit_level;d++) fprintf(stderr,"  ");
-    fprintf(stderr,"%s;\n", ID_FROM_INT(p,e)->name->str);
-  }
-}
-#endif
-
-
 static void push_locals()
 {
   struct locals *l;
@@ -1153,8 +1146,9 @@ static void push_locals()
   l->current_type=0;
   l->current_return_type=0;
   l->next=local_variables;
+  l->current_number_of_locals=0;
+  l->max_number_of_locals=0;
   local_variables=l;
-  local_variables->current_number_of_locals=0;
 }
 
 static void pop_locals()
diff --git a/src/las.h b/src/las.h
index 7099eeecec..7eb94a49c3 100644
--- a/src/las.h
+++ b/src/las.h
@@ -26,6 +26,7 @@ struct locals
   struct lpc_string *current_type;
   struct lpc_string *current_return_type;
   int current_number_of_locals;
+  int max_number_of_locals;
   struct local_variable variable[MAX_LOCAL];
 };
 
diff --git a/src/lex.c b/src/lex.c
index 9045ddab1a..ae13185b36 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -1933,12 +1933,6 @@ static void start_new()
 
   free_all_defines();
 
-  if(!local_variables)
-    local_variables=ALLOC_STRUCT(locals);
-  local_variables->next=0;
-  local_variables->current_number_of_locals=0;
-  local_variables->current_type=0;
-  local_variables->current_return_type=0;
   simple_add_define("__uLPC__", "1",0);
   
   for (tmpf=lpc_predefs; tmpf; tmpf=tmpf->next)
@@ -1978,25 +1972,10 @@ void start_new_string(char *s,INT32 len,struct lpc_string *name)
 
 void end_new_file()
 {
-  while(local_variables)
+  if(current_file)
   {
-    int e;
-    struct locals *l;
-    for(e=0;e<local_variables->current_number_of_locals;e++)
-    {
-      free_string(local_variables->variable[e].name);
-      free_string(local_variables->variable[e].type);
-    }
-  
-    if(local_variables->current_type)
-      free_string(local_variables->current_type);
-
-    if(local_variables->current_return_type)
-      free_string(local_variables->current_return_type);
-
-    l=local_variables->next;
-    free((char *)local_variables);
-    local_variables=l;
+    free_string(current_file);
+    current_file=0;
   }
 
   free_inputstate(istate);
diff --git a/src/modules/files/file.c b/src/modules/files/file.c
index edf6a1b148..2d08ecc940 100644
--- a/src/modules/files/file.c
+++ b/src/modules/files/file.c
@@ -62,6 +62,9 @@ static int fd_references[MAX_OPEN_FILEDESCRIPTORS];
 static char open_mode[MAX_OPEN_FILEDESCRIPTORS];
 static struct program *file_program;
 
+static void file_read_callback(int fd, void *data);
+static void file_write_callback(int fd, void *data);
+
 static void reference_fd(int fd)
 {
   fd_references[fd]++;
@@ -309,7 +312,29 @@ static void do_close(struct file *f, int flags)
   if(f->fd == -1) return; /* already closed */
 
   flags &= open_mode[f->fd];
-  
+
+  if(flags & FILE_READ)
+  {
+    if(f->fd != -1 &&
+       query_read_callback(f->fd) == file_read_callback &&
+       query_read_callback_data(f->fd) == (void *) f &&
+       f->read_callback.type!=T_INT)
+    {
+      set_read_callback(f->fd,0,0);
+    }
+  }
+
+  if(flags & FILE_WRITE)
+  {
+    if(f->fd != -1 &&
+       query_write_callback(f->fd) == file_write_callback &&
+       query_write_callback_data(f->fd) == (void *) f &&
+       f->write_callback.type!=T_INT)
+    {
+      set_write_callback(f->fd,0,0);
+    }
+  }
+
   switch(flags & (FILE_READ | FILE_WRITE))
   {
   case 0:
@@ -317,8 +342,6 @@ static void do_close(struct file *f, int flags)
 
   case FILE_READ:
     open_mode[f->fd] &=~ FILE_READ;
-
-    set_read_callback(f->fd, 0, 0);
     if(open_mode[f->fd] & FILE_WRITE)
     {
       shutdown(f->fd, 0);
@@ -330,9 +353,6 @@ static void do_close(struct file *f, int flags)
 
   case FILE_WRITE:
     open_mode[f->fd] &=~ FILE_WRITE;
-
-    set_write_callback(f->fd, 0, 0);
-    
     if(open_mode[f->fd] & FILE_READ)
     {
       shutdown(f->fd, 1);
@@ -344,10 +364,6 @@ static void do_close(struct file *f, int flags)
 
   case FILE_READ | FILE_WRITE:
     open_mode[f->fd] &=~ (FILE_WRITE | FILE_WRITE);
-
-    set_read_callback(f->fd, 0, 0);
-    set_write_callback(f->fd, 0, 0);
-    
     close_fd(f->fd);
     f->fd=-1;
     break;
@@ -556,14 +572,18 @@ static void file_set_nonblocking(INT32 args)
   if(THIS->fd >= 0)
   {
     if(IS_ZERO(& THIS->read_callback))
+    {
       set_read_callback(THIS->fd, 0,0);
-    else
+    }else{
       set_read_callback(THIS->fd, file_read_callback, (void *)THIS);
+    }
 
     if(IS_ZERO(& THIS->write_callback))
+    {
       set_write_callback(THIS->fd, 0,0);
-    else
+    }else{
       set_write_callback(THIS->fd, file_write_callback, (void *)THIS);
+    }
     set_nonblocking(THIS->fd,1);
   }
 
@@ -837,19 +857,7 @@ static void exit_file_struct(char *foo, struct object *o)
 {
   struct file *f;
   f=(struct file *) foo;
-  if(f->fd != -1 &&
-     query_read_callback(f->fd) == file_read_callback &&
-     query_read_callback_data(f->fd) == (void *) f)
-  {
-    set_read_callback(f->fd,0,0);
-  }
 
-  if(f->fd != -1 &&
-     query_write_callback(f->fd) == file_write_callback &&
-     query_write_callback_data(f->fd) == (void *) f)
-  {
-    set_write_callback(f->fd,0,0);
-  }
   do_close(f,FILE_READ | FILE_WRITE);
   free_svalue(& f->id);
   free_svalue(& f->read_callback);
diff --git a/src/program.c b/src/program.c
index 221dff1597..a46c0d3842 100644
--- a/src/program.c
+++ b/src/program.c
@@ -18,6 +18,7 @@
 #include "docode.h"
 #include "interpret.h"
 #include "hashtable.h"
+#include "main.h"
 #include <stdio.h>
 #include <fcntl.h>
 
@@ -114,6 +115,12 @@ void start_new_program()
   name=make_shared_string("this");
   low_my_binary_strcat((char *)&name,sizeof(name),&inherit_names);
   num_parse_error=0;
+
+    local_variables=ALLOC_STRUCT(locals);
+  local_variables->next=0;
+  local_variables->current_number_of_locals=0;
+  local_variables->current_type=0;
+  local_variables->current_return_type=0;
 }
 
 static void low_free_program(struct program *p)
@@ -150,6 +157,40 @@ void really_free_program(struct program *p)
   free((char *)p);
 }
 
+#ifdef DEBUG
+void dump_program_desc(struct program *p)
+{
+  int e,d,q;
+/*  fprintf(stderr,"Program '%s':\n",p->name->str); */
+
+/*
+  fprintf(stderr,"All inherits:\n");
+  for(e=0;e<p->num_inherits;e++)
+  {
+    fprintf(stderr,"%3d:",e);
+    for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr,"  ");
+    fprintf(stderr,"%s\n",p->inherits[e].prog->name->str);
+  }
+*/
+
+  fprintf(stderr,"All identifiers:\n");
+  for(e=0;e<(int)p->num_identifier_references;e++)
+  {
+    fprintf(stderr,"%3d:",e);
+    for(d=0;d<INHERIT_FROM_INT(p,e)->inherit_level;d++) fprintf(stderr,"  ");
+    fprintf(stderr,"%s;\n",ID_FROM_INT(p,e)->name->str);
+  }
+  fprintf(stderr,"All sorted identifiers:\n");
+  for(q=0;q<(int)p->num_identifier_indexes;q++)
+  {
+    e=p->identifier_index[q];
+    fprintf(stderr,"%3d (%3d):",e,q);
+    for(d=0;d<INHERIT_FROM_INT(p,e)->inherit_level;d++) fprintf(stderr,"  ");
+    fprintf(stderr,"%s;\n", ID_FROM_INT(p,e)->name->str);
+  }
+}
+#endif
+
 /*
  * Something went wrong.
  * toss resources of program we were building
@@ -425,13 +466,31 @@ struct program *end_program()
 
 #ifdef DEBUG
     check_program(prog,0);
+    if(l_flag)
+      dump_program_desc(prog);
 #endif
   }
 
-  if(current_file)
+  /* Clean up */
+  while(local_variables)
   {
-    free_string(current_file);
-    current_file=0;
+    int e;
+    struct locals *l;
+    for(e=0;e<local_variables->current_number_of_locals;e++)
+    {
+      free_string(local_variables->variable[e].name);
+      free_string(local_variables->variable[e].type);
+    }
+  
+    if(local_variables->current_type)
+      free_string(local_variables->current_type);
+
+    if(local_variables->current_return_type)
+      free_string(local_variables->current_return_type);
+
+    l=local_variables->next;
+    free((char *)local_variables);
+    local_variables=l;
   }
 
 #define PROGRAM_STATE
@@ -439,7 +498,7 @@ struct program *end_program()
 #include "compilation.h"
 #undef POP
 #undef PROGRAM_STATE
-  
+
   return prog;
 }
 
@@ -761,11 +820,14 @@ INT32 define_function(struct lpc_string *name,
     funp=ID_FROM_INT(&fake_program, i);
     ref=fake_program.identifier_references[i];
 
-    if((!func || func->offset == -1) || /* not defined */
-       ((funp->func.offset == -1) &&   /* not defined */
-	(ref.inherit_offset==0)         /* not inherited */
-	))
+    if(ref.inherit_offset == 0) /* not inherited */
     {
+      if(!(!func || func->offset == -1) && !(funp->func.offset == -1))
+      {
+	my_yyerror("Redeclaration of function %s.",name->str);
+	return i;
+      }
+
       /* match types against earlier prototype or vice versa */
       if(!match_types(type, funp->type))
       {
@@ -773,14 +835,6 @@ INT32 define_function(struct lpc_string *name,
       }
     }
 
-    if(!(!func || func->offset == -1) &&
-       !(funp->func.offset == -1) &&
-       (ref.inherit_offset == 0)) /* not inherited */
-    {
-      my_yyerror("Redeclaration of function %s.",name->str);
-      return i;
-    }
-
     /* it's just another prototype, don't define anything */
     if(!func || func->offset == -1) return i;
 
@@ -1135,17 +1189,16 @@ struct program *compile_file(struct lpc_string *file_name)
     error("Couldn't open file '%s'.\n",file_name->str);
 
 
-  start_new_program();
-
 #define FILE_STATE
 #define PUSH
 #include "compilation.h"
 #undef PUSH
 
   start_new_file(fd,file_name);
+  start_new_program();
   compile();
-  end_new_file();
   p=end_program();
+  end_new_file();
 
 #define POP
 #include "compilation.h"
@@ -1160,7 +1213,6 @@ struct program *compile_string(struct lpc_string *prog,
 			       struct lpc_string *name)
 {
   struct program *p;
-  start_new_program();
 
 #define FILE_STATE
 #define PUSH
@@ -1168,9 +1220,10 @@ struct program *compile_string(struct lpc_string *prog,
 #undef PUSH
 
   start_new_string(prog->str,prog->len,name);
+  start_new_program();
   compile();
-  end_new_file();
   p=end_program();
+  end_new_file();
 
 #define POP
 #include "compilation.h"
-- 
GitLab