grand merge
authorMario de Sousa <msousa@fe.up.pt>
Thu, 03 Jan 2013 18:23:07 +0000
changeset 793 268bf4ca5fa1
parent 785 b08167f156a1 (current diff)
parent 713 e3ca0f4d47b3 (diff)
child 795 9c1bca18d3fa
grand merge
absyntax_utils/search_base_type.cc
absyntax_utils/search_base_type.hh
absyntax_utils/search_var_instance_decl.cc
lib/iec_std_lib.h
stage1_2/iec_flex.ll
stage4/generate_c/generate_c.cc
stage4/generate_c/generate_c_base.cc
stage4/generate_c/generate_c_il.cc
stage4/generate_c/generate_c_inlinefcall.cc
stage4/generate_c/generate_c_sfc.cc
stage4/generate_c/generate_c_st.cc
stage4/generate_c/generate_c_typedecl.cc
stage4/generate_c/generate_c_vardecl.cc
stage4/generate_c/generate_var_list.cc
--- a/absyntax_utils/search_base_type.cc	Thu Jan 03 17:04:04 2013 +0000
+++ b/absyntax_utils/search_base_type.cc	Thu Jan 03 18:23:07 2013 +0000
@@ -102,6 +102,12 @@
   return search_base_type_singleton->is_enumerated;
 }
 
+bool search_base_type_c::type_is_fb(symbol_c* type_decl) {
+  create_singleton();
+  search_base_type_singleton->is_fb = false;
+  type_decl->accept(*search_base_type_singleton);
+  return search_base_type_singleton->is_fb;
+}
 
 /*************************/
 /* B.1 - Common elements */
@@ -373,7 +379,10 @@
 /*****************************/
 /*  FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */
 // SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body)
-void *search_base_type_c::visit(function_block_declaration_c *symbol)                   {return (void *)symbol;}
+void *search_base_type_c::visit(function_block_declaration_c *symbol)                   {
+	this->is_fb = true;
+	return (void *)symbol;
+}
 
 
 
--- a/absyntax_utils/search_base_type.hh	Thu Jan 03 17:04:04 2013 +0000
+++ b/absyntax_utils/search_base_type.hh	Thu Jan 03 18:23:07 2013 +0000
@@ -56,6 +56,7 @@
     bool is_array;
     bool is_subrange;
     bool is_enumerated;
+    bool is_fb;
     static search_base_type_c *search_base_type_singleton; // Make this a singleton class!
     
   private:  
@@ -67,6 +68,7 @@
     static symbol_c *get_basetype_id   (symbol_c *symbol);
     static bool      type_is_subrange  (symbol_c *type_decl);
     static bool      type_is_enumerated(symbol_c *type_decl);
+    static bool      type_is_fb        (symbol_c *type_decl);
 
   public:
   /*************************/
@@ -119,7 +121,7 @@
     void *visit(lreal_type_name_c *symbol);
     void *visit(date_type_name_c *symbol);
     void *visit(tod_type_name_c *symbol);
-    void *visit(dt_type_name_c *symbol)	;
+    void *visit(dt_type_name_c *symbol);
     void *visit(byte_type_name_c *symbol);
     void *visit(word_type_name_c *symbol);
     void *visit(dword_type_name_c *symbol);
@@ -148,7 +150,7 @@
     void *visit(safelreal_type_name_c *symbol);
     void *visit(safedate_type_name_c *symbol);
     void *visit(safetod_type_name_c *symbol);
-    void *visit(safedt_type_name_c *symbol)	;
+    void *visit(safedt_type_name_c *symbol);
     void *visit(safebyte_type_name_c *symbol);
     void *visit(safeword_type_name_c *symbol);
     void *visit(safedword_type_name_c *symbol);
@@ -225,7 +227,7 @@
     void *visit(structure_element_initialization_c *symbol);
   /*  string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */
   /*
-  SYM_REF4(string_type_declaration_c,	string_type_name,
+  SYM_REF4(string_type_declaration_c, string_type_name,
   					elementary_string_type_name,
   					string_type_declaration_size,
   					string_type_declaration_init) // may be == NULL!
--- a/absyntax_utils/search_fb_instance_decl.cc	Thu Jan 03 17:04:04 2013 +0000
+++ b/absyntax_utils/search_fb_instance_decl.cc	Thu Jan 03 18:23:07 2013 +0000
@@ -102,6 +102,13 @@
   return NULL;
 }
 
+/* name_list ',' fb_name */
+void *search_fb_instance_decl_c::visit(external_declaration_c *symbol) {
+  if (compare_identifiers(symbol->global_var_name, search_name) == 0)
+	return symbol->specification;
+  return NULL;
+}
+
 /**************************************/
 /* B.1.5 - Program organization units */
 /**************************************/
--- a/absyntax_utils/search_fb_instance_decl.hh	Thu Jan 03 17:04:04 2013 +0000
+++ b/absyntax_utils/search_fb_instance_decl.hh	Thu Jan 03 18:23:07 2013 +0000
@@ -88,6 +88,9 @@
     void *visit(fb_name_decl_c *symbol);
   /* name_list ',' fb_name */
     void *visit(fb_name_list_c *symbol);
+  /*  global_var_name ':' (simple_specification|subrange_specification|enumerated_specification|array_specification|prev_declared_structure_type_name|function_block_type_name */
+    void *visit(external_declaration_c *symbol);
+
 
   /**************************************/
   /* B.1.5 - Program organization units */
--- a/absyntax_utils/search_var_instance_decl.cc	Thu Jan 03 17:04:04 2013 +0000
+++ b/absyntax_utils/search_var_instance_decl.cc	Thu Jan 03 18:23:07 2013 +0000
@@ -143,12 +143,19 @@
           (typeid( *(decl) ) == typeid( structure_type_declaration_c         )) ||  
           (typeid( *(decl) ) == typeid( structure_element_declaration_list_c )) ||
 //        (typeid( *(decl) ) == typeid( structure_type_declaration_c         )) ||  /* does not seem to be necessary */
-          (typeid( *(decl) ) == typeid( initialized_structure_c              ))
-          
+          (typeid( *(decl) ) == typeid( initialized_structure_c              )) ||
+          (search_base_type_c::type_is_fb(decl) && current_vartype == external_vt)
          );
 }
 
-
+bool search_var_instance_decl_c::type_is_fb(symbol_c *symbol) {
+    symbol_c *decl;
+    search_base_type_c search_base_type;
+
+    decl = this->get_decl(symbol);
+    if (NULL == decl) ERROR;
+    return search_base_type.type_is_fb(decl);
+}
 
 /***************************/
 /* B 0 - Programming Model */
--- a/absyntax_utils/search_var_instance_decl.hh	Thu Jan 03 17:04:04 2013 +0000
+++ b/absyntax_utils/search_var_instance_decl.hh	Thu Jan 03 18:23:07 2013 +0000
@@ -140,7 +140,7 @@
      */
     bool type_is_complex(symbol_c *variable_name);
 
-    
+    bool type_is_fb(symbol_c *symbol);
     
   private:
     symbol_c *search_scope;
--- a/lib/accessor.h	Thu Jan 03 17:04:04 2013 +0000
+++ b/lib/accessor.h	Thu Jan 03 18:23:07 2013 +0000
@@ -18,6 +18,13 @@
 	type* __GET_GLOBAL_##name(void) {\
 		return &((*GLOBAL__##name).value);\
 	}
+#define __DECLARE_GLOBAL_FB(type, domain, name)\
+	type domain##__##name;\
+	static type *GLOBAL__##name = &(domain##__##name);\
+	type* __GET_GLOBAL_##name(void) {\
+		return &(*GLOBAL__##name);\
+	}\
+	extern void type##_init__(type* data__, BOOL retain);
 #define __DECLARE_GLOBAL_LOCATION(type, location)\
 	extern type *location;
 #define __DECLARE_GLOBAL_LOCATED(type, resource, name)\
@@ -33,9 +40,11 @@
 		return (*GLOBAL__##name).value;\
 	}
 #define __DECLARE_GLOBAL_PROTOTYPE(type, name)\
-    extern type* __GET_GLOBAL_##name();
+    extern type* __GET_GLOBAL_##name(void);
 #define __DECLARE_EXTERNAL(type, name)\
 	__IEC_##type##_p name;
+#define __DECLARE_EXTERNAL_FB(type, name)\
+	type* name;
 #define __DECLARE_LOCATED(type, name)\
 	__IEC_##type##_p name;
 
@@ -52,6 +61,8 @@
 	    __INIT_GLOBAL_##name(temp);\
 	    __INIT_RETAIN((*GLOBAL__##name), retained)\
     }
+#define __INIT_GLOBAL_FB(type, name, retained)\
+	type##_init__(&(*GLOBAL__##name), retained);
 #define __INIT_GLOBAL_LOCATED(domain, name, location, retained)\
 	domain##__##name.value = location;\
 	__INIT_RETAIN(domain##__##name, retained)
@@ -60,6 +71,8 @@
 		name.value = __GET_GLOBAL_##global();\
 		__INIT_RETAIN(name, retained)\
     }
+#define __INIT_EXTERNAL_FB(type, global, name, retained)\
+	name = __GET_GLOBAL_##global();
 #define __INIT_LOCATED(type, location, name, retained)\
 	{\
 		extern type *location;\
@@ -75,12 +88,16 @@
 	name.value __VA_ARGS__
 #define __GET_EXTERNAL(name, ...)\
 	((name.flags & __IEC_FORCE_FLAG) ? name.fvalue __VA_ARGS__ : (*(name.value)) __VA_ARGS__)
+#define __GET_EXTERNAL_FB(name, ...)\
+	__GET_VAR(((*name) __VA_ARGS__))
 #define __GET_LOCATED(name, ...)\
 	((name.flags & __IEC_FORCE_FLAG) ? name.fvalue __VA_ARGS__ : (*(name.value)) __VA_ARGS__)
 #define __GET_VAR_BY_REF(name, ...)\
 	((name.flags & __IEC_FORCE_FLAG) ? &(name.fvalue __VA_ARGS__) : &(name.value __VA_ARGS__))
 #define __GET_EXTERNAL_BY_REF(name, ...)\
 	((name.flags & __IEC_FORCE_FLAG) ? &(name.fvalue __VA_ARGS__) : &((*(name.value)) __VA_ARGS__))
+#define __GET_EXTERNAL_FB_BY_REF(name, ...)\
+	__GET_EXTERNAL_BY_REF(((*name) __VA_ARGS__))
 #define __GET_LOCATED_BY_REF(name, ...)\
 	((name.flags & __IEC_FORCE_FLAG) ? &(name.fvalue __VA_ARGS__) : &((*(name.value)) __VA_ARGS__))
 
@@ -90,6 +107,8 @@
 #define __SET_EXTERNAL(prefix, name, new_value, ...)\
 	if (!(prefix name.flags & __IEC_FORCE_FLAG || __IS_GLOBAL_##name##_FORCED()))\
 		(*(prefix name.value)) __VA_ARGS__ = new_value
+#define __SET_EXTERNAL_FB(prefix, name, new_value, ...)\
+	__SET_VAR((*(prefix name)), __VA_ARGS__, new_value)
 #define __SET_LOCATED(prefix, name, new_value, ...)\
 	if (!(prefix name.flags & __IEC_FORCE_FLAG)) *(prefix name.value) __VA_ARGS__ = new_value
 
--- a/lib/create_standard_function_txt.sh	Thu Jan 03 17:04:04 2013 +0000
+++ b/lib/create_standard_function_txt.sh	Thu Jan 03 18:23:07 2013 +0000
@@ -206,8 +206,10 @@
 /* Not supported: DT_TO_TIME */
 /*__iec_(to_TYPENAME,from_TYPENAME)*/
 __iec_(DATE,DT)
+__function_1p(DATE_AND_TIME_TO_DATE, DATE, IN, DT)
 __iec_(DT,DT)
 __iec_(TOD,DT)
+__function_1p(DATE_AND_TIME_TO_TIME_OF_DAY, TOD, IN, DT)
 /* Not supported: DATE_TO_TIME */
 __iec_(DATE,DATE)
 /* Not supported: DATE_TO_DT */
@@ -217,7 +219,6 @@
 /* Not supported: TOD_TO_DT */
 __iec_(TOD,TOD)
 
-
 /******** TIME_TO_[ANY_DATE]   ************/ 
 /* Not supported: TIME_TO_DATE */
 /* Not supported: TIME_TO_DT */
@@ -273,7 +274,9 @@
 /*******************/
 /*   *_TO_BCD_*    */
 /*******************/
-#define __iec_(to_TYPENAME,from_TYPENAME) __function_1p(from_TYPENAME##_TO_BCD_##to_TYPENAME, to_TYPENAME, IN, from_TYPENAME)
+#define __iec_(to_TYPENAME,from_TYPENAME)\
+__function_1p(from_TYPENAME##_TO_BCD_##to_TYPENAME, to_TYPENAME, IN, from_TYPENAME)  /* explicitly typed function */\
+__function_1p(from_TYPENAME##_TO_BCD, to_TYPENAME, IN, from_TYPENAME)                /* overloaded function */ 
 __ANY_UINT(__to_anynbit_)
 #undef __iec_
 
@@ -281,7 +284,10 @@
 /*******************/
 /*   *_BCD_TO_*    */
 /*******************/
-#define __iec_(to_TYPENAME,from_TYPENAME) __function_1p(from_TYPENAME##_BCD_TO_##to_TYPENAME, to_TYPENAME, IN, from_TYPENAME)
+#define __iec_(to_TYPENAME,from_TYPENAME)\
+__function_1p(from_TYPENAME##_BCD_TO_##to_TYPENAME, to_TYPENAME, IN, from_TYPENAME)  /* explicitly typed function */\
+__function_1p(BCD_TO_##to_TYPENAME, to_TYPENAME, IN, from_TYPENAME)                  /* overloaded function */ 
+
 __ANY_NBIT(__to_anyuint_)
 #undef __iec_
 
--- a/lib/iec_std_lib.h	Thu Jan 03 17:04:04 2013 +0000
+++ b/lib/iec_std_lib.h	Thu Jan 03 18:23:07 2013 +0000
@@ -33,8 +33,8 @@
 #include <limits.h>
 #include <float.h>
 #include <math.h>
-#include <time.h>
 #include <stdint.h>
+#include <ctype.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -87,7 +87,7 @@
 
 #define __lit(type,value,...) (type)value##__VA_ARGS__
 // Keep this macro expention step to let sfx(__VA_ARGS__) change into L or LL
-#define __literal(type,value,...) __lit(type,value,##__VA_ARGS__)
+#define __literal(type,value,...) __lit(type,value,__VA_ARGS__)
 
 #define __BOOL_LITERAL(value) __literal(BOOL,value)
 #define __SINT_LITERAL(value) __literal(SINT,value)
@@ -227,54 +227,96 @@
   return ts;
 }
 
+#define EPOCH_YEAR 1970
+#define SECONDS_PER_HOUR (60 * 60)
+#define SECONDS_PER_DAY (24 * SECONDS_PER_HOUR)
+#define __isleap(year) \
+  ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
+static const unsigned short int __mon_yday[2][13] =
+{
+  /* Normal years.  */
+  { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
+  /* Leap years.  */
+  { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}
+};
+
+typedef struct {
+	int tm_sec;			/* Seconds.	[0-60] (1 leap second) */
+	int tm_min;			/* Minutes.	[0-59] */
+	int tm_hour;		/* Hours.	[0-23] */
+	int tm_day;			/* Day.		[1-31] */
+	int tm_mon;			/* Month.	[0-11] */
+	int tm_year;		/* Year	*/
+} tm;
+
+static inline tm convert_seconds_to_date_and_time(long int seconds) {
+  tm dt;
+  long int days, rem;
+  days = seconds / SECONDS_PER_DAY;
+  rem = seconds % SECONDS_PER_DAY;
+  if (rem < 0) {
+	  rem += SECONDS_PER_DAY;
+	  days--;
+  }
+
+  // time of day
+  dt.tm_hour = rem / SECONDS_PER_HOUR;
+  rem %= SECONDS_PER_HOUR;
+  dt.tm_min = rem / 60;
+  dt.tm_sec = rem % 60;
+
+  // date
+  dt.tm_year = EPOCH_YEAR;
+  while (days >= (rem = __isleap(dt.tm_year) ? 366 : 365)) {
+	  dt.tm_year++;
+	  days -= rem;
+  }
+  while (days < 0) {
+	  dt.tm_year--;
+	  days += __isleap(dt.tm_year) ? 366 : 365;
+  }
+  dt.tm_mon = 1;
+  while (days > __mon_yday[__isleap(dt.tm_year)][dt.tm_mon]) {
+	  dt.tm_mon += 1;
+  }
+  dt.tm_day = days - __mon_yday[__isleap(dt.tm_year)][dt.tm_mon - 1] + 1;
+
+  return dt;
+}
+
 static inline IEC_TIMESPEC __date_to_timespec(int day, int month, int year) {
   IEC_TIMESPEC ts;
-  struct tm broken_down_time;
-  time_t epoch_seconds;
-
-  broken_down_time.tm_sec = 0;
-  broken_down_time.tm_min = 0;
-  broken_down_time.tm_hour = 0;
-  broken_down_time.tm_mday = day;  /* day of month, from 1 to 31 */
-  broken_down_time.tm_mon = month - 1;   /* month since January, in the range 0 to 11 */
-  broken_down_time.tm_year = year - 1900;  /* number of years since 1900 */
-
-  epoch_seconds = mktime(&broken_down_time); /* determine number of seconds since the epoch, i.e. Jan 1st 1970 */
-
-  if ((time_t)(-1) == epoch_seconds)
-    __iec_error();
-
-  ts.tv_sec = epoch_seconds;
+  int a4, b4, a100, b100, a400, b400;
+  int yday;
+  int intervening_leap_days;
+
+  if (month < 1 || month > 12)
+	 __iec_error();
+
+  yday = __mon_yday[__isleap(year)][month - 1] + day;
+
+  if (yday > __mon_yday[__isleap(year)][month])
+	  __iec_error();
+
+  a4 = (year >> 2) - ! (year & 3);
+  b4 = (EPOCH_YEAR >> 2) - ! (EPOCH_YEAR & 3);
+  a100 = a4 / 25 - (a4 % 25 < 0);
+  b100 = b4 / 25 - (b4 % 25 < 0);
+  a400 = a100 >> 2;
+  b400 = b100 >> 2;
+  intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
+  
+  ts.tv_sec = ((year - EPOCH_YEAR) * 365 + intervening_leap_days + yday - 1) * 24 * 60 * 60;
   ts.tv_nsec = 0;
 
   return ts;
 }
 
-static inline IEC_TIMESPEC __dt_to_timespec(double seconds,  double minutes, double hours, int day, int month, int year) {
-  IEC_TIMESPEC ts;
-  struct tm broken_down_time;
-  time_t epoch_seconds;
-
-  long double total_sec = (hours*60 + minutes)*60 + seconds;
-  ts.tv_sec = (long int)total_sec;
-  ts.tv_nsec = (long int)((total_sec - ts.tv_sec)*1e9);
-
-  broken_down_time.tm_sec = 0;
-  broken_down_time.tm_min = 0;
-  broken_down_time.tm_hour = 0;
-  broken_down_time.tm_mday = day;  /* day of month, from 1 to 31 */
-  broken_down_time.tm_mon = month - 1;   /* month since January, in the range 0 to 11 */
-  broken_down_time.tm_year = year - 1900;  /* number of years since 1900 */
-  broken_down_time.tm_isdst = 0; /* disable daylight savings time */
-
-  epoch_seconds = mktime(&broken_down_time); /* determine number of seconds since the epoch, i.e. Jan 1st 1970 */
-  if ((time_t)(-1) == epoch_seconds)
-    __iec_error();
-
-  ts.tv_sec += epoch_seconds;
-  if (ts.tv_sec < epoch_seconds)
-    /* since the TOD is always positive, if the above happens then we had an overflow */
-    __iec_error();
+static inline IEC_TIMESPEC __dt_to_timespec(double seconds, double minutes, double hours, int day, int month, int year) {
+  IEC_TIMESPEC ts_date = __date_to_timespec(day, month, year);
+  IEC_TIMESPEC ts = __tod_to_timespec(seconds, minutes, hours);
+
+  ts.tv_sec += ts_date.tv_sec;
 
   return ts;
 }
@@ -374,7 +416,10 @@
     /* FROM_STRING */
     /***************/
 static inline BOOL __string_to_bool(STRING IN) {
-    return IN.len == 5 ? !memcmp(&IN.body,"TRUE", IN.len) : 0;
+    int i;
+    if (IN.len == 1) return !memcmp(&IN.body,"1", IN.len);
+    for (i = 0; i < IN.len; i++) IN.body[i] = toupper(IN.body[i]);
+    return IN.len == 4 ? !memcmp(&IN.body,"TRUE", IN.len) : 0;
 }
 
 static inline LINT __pstring_to_sint(STRING* IN) {
@@ -529,64 +574,64 @@
 }
 static inline STRING __date_to_string(DATE IN){
     STRING res;
-    struct tm* broken_down_time;
-    time_t seconds;
+    tm broken_down_time;
     /* D#1984-06-25 */
+    broken_down_time = convert_seconds_to_date_and_time(IN.tv_sec);
     res = __INIT_STRING;
-    seconds = IN.tv_sec;
-    if (NULL == (broken_down_time = localtime(&seconds))){ /* get the UTC (GMT) broken down time */
-        __iec_error();
-        return (STRING){7,"D#ERROR"};
-    }
-    res.len = snprintf((char*)&res.body, STR_MAX_LEN, "D#%d-%2.2d-%2.2d", broken_down_time->tm_year + 1900, broken_down_time->tm_mon + 1, broken_down_time->tm_mday);
+    res.len = snprintf((char*)&res.body, STR_MAX_LEN, "D#%d-%2.2d-%2.2d",
+             broken_down_time.tm_year,
+             broken_down_time.tm_mon,
+             broken_down_time.tm_day);
     if(res.len > STR_MAX_LEN) res.len = STR_MAX_LEN;
     return res;
 }
 static inline STRING __tod_to_string(TOD IN){
     STRING res;
-    struct tm* broken_down_time;
+    tm broken_down_time;
     time_t seconds;
     /* TOD#15:36:55.36 */
+    seconds = IN.tv_sec;
+    if (seconds >= SECONDS_PER_DAY){
+		__iec_error();
+		return (STRING){9,"TOD#ERROR"};
+	}
+    broken_down_time = convert_seconds_to_date_and_time(seconds);
     res = __INIT_STRING;
-    seconds = IN.tv_sec;
-    if (NULL == (broken_down_time = localtime(&seconds))){ /* get the UTC (GMT) broken down time */
-        __iec_error();
-        return (STRING){9,"TOD#ERROR"};
-    }
     if(IN.tv_nsec == 0){
-        res.len = snprintf((char*)&res.body, STR_MAX_LEN, "TOD#%2.2d:%2.2d:%d", broken_down_time->tm_hour, broken_down_time->tm_min, broken_down_time->tm_sec);
+        res.len = snprintf((char*)&res.body, STR_MAX_LEN, "TOD#%2.2d:%2.2d:%2.2d",
+                 broken_down_time.tm_hour,
+                 broken_down_time.tm_min,
+                 broken_down_time.tm_sec);
     }else{
-        res.len = snprintf((char*)&res.body, STR_MAX_LEN, "TOD#%2.2d:%2.2d:%g", broken_down_time->tm_hour, broken_down_time->tm_min, (LREAL)broken_down_time->tm_sec + (LREAL)IN.tv_nsec / 1e9);
+        res.len = snprintf((char*)&res.body, STR_MAX_LEN, "TOD#%2.2d:%2.2d:%09.6g",
+                 broken_down_time.tm_hour,
+                 broken_down_time.tm_min,
+                 (LREAL)broken_down_time.tm_sec + (LREAL)IN.tv_nsec / 1e9);
     }
     if(res.len > STR_MAX_LEN) res.len = STR_MAX_LEN;
     return res;
 }
 static inline STRING __dt_to_string(DT IN){
     STRING res;
-    struct tm* broken_down_time;
-    time_t seconds;
+    tm broken_down_time;
     /* DT#1984-06-25-15:36:55.36 */
-    seconds = IN.tv_sec;
-    if (NULL == (broken_down_time = localtime(&seconds))){ /* get the UTC (GMT) broken down time */
-        __iec_error();
-        return (STRING){8,"DT#ERROR"};
-    }
+    broken_down_time = convert_seconds_to_date_and_time(IN.tv_sec);
     if(IN.tv_nsec == 0){
-        res.len = snprintf((char*)&res.body, STR_MAX_LEN, "DT#%d-%2.2d-%2.2d-%2.2d:%2.2d:%d",
-                 broken_down_time->tm_year + 1900,
-                 broken_down_time->tm_mon  + 1,
-                 broken_down_time->tm_mday,
-                 broken_down_time->tm_hour,
-                 broken_down_time->tm_min,
-                 broken_down_time->tm_sec);
+        res.len = snprintf((char*)&res.body, STR_MAX_LEN, "DT#%d-%2.2d-%2.2d-%2.2d:%2.2d:%2.2d",
+                 broken_down_time.tm_year,
+                 broken_down_time.tm_mon,
+                 broken_down_time.tm_day,
+                 broken_down_time.tm_hour,
+                 broken_down_time.tm_min,
+                 broken_down_time.tm_sec);
     }else{
-        res.len = snprintf((char*)&res.body, STR_MAX_LEN, "DT#%d-%2.2d-%2.2d-%2.2d:%2.2d:%g",
-                 broken_down_time->tm_year + 1900,
-                 broken_down_time->tm_mon  + 1,
-                 broken_down_time->tm_mday,
-                 broken_down_time->tm_hour,
-                 broken_down_time->tm_min,
-                 (LREAL)broken_down_time->tm_sec + ((LREAL)IN.tv_nsec / 1e9));
+        res.len = snprintf((char*)&res.body, STR_MAX_LEN, "DT#%d-%2.2d-%2.2d-%2.2d:%2.2d:%09.6g",
+                 broken_down_time.tm_year,
+                 broken_down_time.tm_mon,
+                 broken_down_time.tm_day,
+                 broken_down_time.tm_hour,
+                 broken_down_time.tm_min,
+                 (LREAL)broken_down_time.tm_sec + ((LREAL)IN.tv_nsec / 1e9));
     }
     if(res.len > STR_MAX_LEN) res.len = STR_MAX_LEN;
     return res;
@@ -596,7 +641,7 @@
     /*  [ANY_DATE | TIME] _TO_ [ANY_DATE | TIME]  */
     /**********************************************/
 
-static inline TOD __date_and_time_to_time_of_day(DT IN) {return (TOD){IN.tv_sec % 86400, IN.tv_nsec};}
+static inline TOD __date_and_time_to_time_of_day(DT IN) {return (TOD){IN.tv_sec % (24*60*60), IN.tv_nsec};}
 static inline DATE __date_and_time_to_date(DT IN){return (DATE){IN.tv_sec - (IN.tv_sec % (24*60*60)), 0};}
 
     /*****************/
@@ -823,8 +868,14 @@
 /******** [ANY_DATE]_TO_[ANY_DATE | TIME]   ************/ 
 /* Not supported: DT_TO_TIME */
 __convert_type(DT, DATE,  __date_and_time_to_date)
+static inline DATE DATE_AND_TIME_TO_DATE(EN_ENO_PARAMS, DT op){
+	return DT_TO_DATE(EN_ENO, op);
+}
 __convert_type(DT, DT,    __move_DT)
 __convert_type(DT, TOD,   __date_and_time_to_time_of_day)
+static inline DATE DATE_AND_TIME_TO_TIME_OF_DAY(EN_ENO_PARAMS, DT op){
+	return DT_TO_TOD(EN_ENO, op);
+}
 /* Not supported: DATE_TO_TIME */
 __convert_type(DATE, DATE, __move_DATE)
 /* Not supported: DATE_TO_DT */
@@ -910,21 +961,27 @@
 #undef __iec_
 
 
-/********   _TO_BCD   ************/ 
+/********   _TO_BCD   ************/
 #define __iec_(to_TYPENAME,from_TYPENAME) \
 static inline to_TYPENAME from_TYPENAME##_TO_BCD_##to_TYPENAME(EN_ENO_PARAMS, from_TYPENAME op){\
   TEST_EN(to_TYPENAME)\
   return (to_TYPENAME)__uint_to_bcd(op);\
+}\
+static inline to_TYPENAME from_TYPENAME##_TO_BCD__##to_TYPENAME##__##from_TYPENAME(EN_ENO_PARAMS, from_TYPENAME op){\
+  return from_TYPENAME##_TO_BCD_##to_TYPENAME(EN_ENO, op);\
 }
 __ANY_UINT(__to_anynbit_)
 #undef __iec_
 
 
-/********   BCD_TO_   ************/ 
+/********   BCD_TO_   ************/
 #define __iec_(to_TYPENAME,from_TYPENAME) \
 static inline to_TYPENAME from_TYPENAME##_BCD_TO_##to_TYPENAME(EN_ENO_PARAMS, from_TYPENAME op){\
   TEST_EN(to_TYPENAME)\
   return (to_TYPENAME)__bcd_to_uint(op);\
+}\
+static inline to_TYPENAME BCD_TO_##to_TYPENAME##__##to_TYPENAME##__##from_TYPENAME(EN_ENO_PARAMS, from_TYPENAME op){\
+  return from_TYPENAME##_BCD_TO_##to_TYPENAME(EN_ENO, op);\
 }
 __ANY_NBIT(__to_anyuint_)
 #undef __iec_
@@ -1769,6 +1826,11 @@
   return __time_cmp(op1, op2) != 0 ? 1 : 0;\
 }
 
+#define __ne_string(fname, TYPENAME) \
+static inline BOOL fname(EN_ENO_PARAMS, TYPENAME op1, TYPENAME op2){\
+  TEST_EN(BOOL)\
+  return __STR_CMP(op1, op2) != 0 ? 1 : 0;\
+}
 
 /* Comparison for numerical data types */
 #define __iec_(TYPENAME) \
@@ -1787,8 +1849,8 @@
 #undef __iec_
 
 /* Comparison for string data types */	
-__compare_string(NE_STRING, != ) /* The explicitly typed standard functions */
-__compare_string(NE__BOOL__STRING__STRING, != ) /* Overloaded function */
+__ne_string(NE_STRING, STRING) /* The explicitly typed standard functions */
+__ne_string(NE__BOOL__STRING__STRING, STRING) /* Overloaded function */
 
 
 
--- a/lib/standard_functions.txt	Thu Jan 03 17:04:04 2013 +0000
+++ b/lib/standard_functions.txt	Thu Jan 03 18:23:07 2013 +0000
@@ -367,8 +367,10 @@
 
 
 FUNCTION DT_TO_DATE : DATE VAR_INPUT IN : DT; END_VAR RETURN; END_FUNCTION
+FUNCTION DATE_AND_TIME_TO_DATE : DATE VAR_INPUT IN : DT; END_VAR RETURN; END_FUNCTION
 FUNCTION DT_TO_DT : DT VAR_INPUT IN : DT; END_VAR RETURN; END_FUNCTION
 FUNCTION DT_TO_TOD : TOD VAR_INPUT IN : DT; END_VAR RETURN; END_FUNCTION
+FUNCTION DATE_AND_TIME_TO_TIME_OF_DAY : TOD VAR_INPUT IN : DT; END_VAR RETURN; END_FUNCTION
 
 FUNCTION DATE_TO_DATE : DATE VAR_INPUT IN : DATE; END_VAR RETURN; END_FUNCTION
 
@@ -377,6 +379,13 @@
 
 
 FUNCTION TOD_TO_TOD : TOD VAR_INPUT IN : TOD; END_VAR RETURN; END_FUNCTION
+
+
+
+
+
+
+
 FUNCTION TIME_TO_TIME : TIME VAR_INPUT IN : TIME; END_VAR RETURN; END_FUNCTION
 
 
@@ -455,52 +464,70 @@
 FUNCTION TRUNC : UINT VAR_INPUT IN : LREAL; END_VAR RETURN; END_FUNCTION
 FUNCTION TRUNC : UDINT VAR_INPUT IN : LREAL; END_VAR RETURN; END_FUNCTION
 FUNCTION TRUNC : ULINT VAR_INPUT IN : LREAL; END_VAR RETURN; END_FUNCTION
-
-
-
-
-
-
-
 FUNCTION USINT_TO_BCD_BYTE : BYTE VAR_INPUT IN : USINT; END_VAR RETURN; END_FUNCTION
+FUNCTION USINT_TO_BCD : BYTE VAR_INPUT IN : USINT; END_VAR RETURN; END_FUNCTION
 FUNCTION USINT_TO_BCD_WORD : WORD VAR_INPUT IN : USINT; END_VAR RETURN; END_FUNCTION
+FUNCTION USINT_TO_BCD : WORD VAR_INPUT IN : USINT; END_VAR RETURN; END_FUNCTION
 FUNCTION USINT_TO_BCD_DWORD : DWORD VAR_INPUT IN : USINT; END_VAR RETURN; END_FUNCTION
+FUNCTION USINT_TO_BCD : DWORD VAR_INPUT IN : USINT; END_VAR RETURN; END_FUNCTION
 FUNCTION USINT_TO_BCD_LWORD : LWORD VAR_INPUT IN : USINT; END_VAR RETURN; END_FUNCTION
+FUNCTION USINT_TO_BCD : LWORD VAR_INPUT IN : USINT; END_VAR RETURN; END_FUNCTION
 FUNCTION UINT_TO_BCD_BYTE : BYTE VAR_INPUT IN : UINT; END_VAR RETURN; END_FUNCTION
+FUNCTION UINT_TO_BCD : BYTE VAR_INPUT IN : UINT; END_VAR RETURN; END_FUNCTION
 FUNCTION UINT_TO_BCD_WORD : WORD VAR_INPUT IN : UINT; END_VAR RETURN; END_FUNCTION
+FUNCTION UINT_TO_BCD : WORD VAR_INPUT IN : UINT; END_VAR RETURN; END_FUNCTION
 FUNCTION UINT_TO_BCD_DWORD : DWORD VAR_INPUT IN : UINT; END_VAR RETURN; END_FUNCTION
+FUNCTION UINT_TO_BCD : DWORD VAR_INPUT IN : UINT; END_VAR RETURN; END_FUNCTION
 FUNCTION UINT_TO_BCD_LWORD : LWORD VAR_INPUT IN : UINT; END_VAR RETURN; END_FUNCTION
+FUNCTION UINT_TO_BCD : LWORD VAR_INPUT IN : UINT; END_VAR RETURN; END_FUNCTION
 FUNCTION UDINT_TO_BCD_BYTE : BYTE VAR_INPUT IN : UDINT; END_VAR RETURN; END_FUNCTION
+FUNCTION UDINT_TO_BCD : BYTE VAR_INPUT IN : UDINT; END_VAR RETURN; END_FUNCTION
 FUNCTION UDINT_TO_BCD_WORD : WORD VAR_INPUT IN : UDINT; END_VAR RETURN; END_FUNCTION
+FUNCTION UDINT_TO_BCD : WORD VAR_INPUT IN : UDINT; END_VAR RETURN; END_FUNCTION
 FUNCTION UDINT_TO_BCD_DWORD : DWORD VAR_INPUT IN : UDINT; END_VAR RETURN; END_FUNCTION
+FUNCTION UDINT_TO_BCD : DWORD VAR_INPUT IN : UDINT; END_VAR RETURN; END_FUNCTION
 FUNCTION UDINT_TO_BCD_LWORD : LWORD VAR_INPUT IN : UDINT; END_VAR RETURN; END_FUNCTION
+FUNCTION UDINT_TO_BCD : LWORD VAR_INPUT IN : UDINT; END_VAR RETURN; END_FUNCTION
 FUNCTION ULINT_TO_BCD_BYTE : BYTE VAR_INPUT IN : ULINT; END_VAR RETURN; END_FUNCTION
+FUNCTION ULINT_TO_BCD : BYTE VAR_INPUT IN : ULINT; END_VAR RETURN; END_FUNCTION
 FUNCTION ULINT_TO_BCD_WORD : WORD VAR_INPUT IN : ULINT; END_VAR RETURN; END_FUNCTION
+FUNCTION ULINT_TO_BCD : WORD VAR_INPUT IN : ULINT; END_VAR RETURN; END_FUNCTION
 FUNCTION ULINT_TO_BCD_DWORD : DWORD VAR_INPUT IN : ULINT; END_VAR RETURN; END_FUNCTION
+FUNCTION ULINT_TO_BCD : DWORD VAR_INPUT IN : ULINT; END_VAR RETURN; END_FUNCTION
 FUNCTION ULINT_TO_BCD_LWORD : LWORD VAR_INPUT IN : ULINT; END_VAR RETURN; END_FUNCTION
-
-
-
-
-
-
-
+FUNCTION ULINT_TO_BCD : LWORD VAR_INPUT IN : ULINT; END_VAR RETURN; END_FUNCTION
 FUNCTION BYTE_BCD_TO_USINT : USINT VAR_INPUT IN : BYTE; END_VAR RETURN; END_FUNCTION
+FUNCTION BCD_TO_USINT : USINT VAR_INPUT IN : BYTE; END_VAR RETURN; END_FUNCTION
 FUNCTION BYTE_BCD_TO_UINT : UINT VAR_INPUT IN : BYTE; END_VAR RETURN; END_FUNCTION
+FUNCTION BCD_TO_UINT : UINT VAR_INPUT IN : BYTE; END_VAR RETURN; END_FUNCTION
 FUNCTION BYTE_BCD_TO_UDINT : UDINT VAR_INPUT IN : BYTE; END_VAR RETURN; END_FUNCTION
+FUNCTION BCD_TO_UDINT : UDINT VAR_INPUT IN : BYTE; END_VAR RETURN; END_FUNCTION
 FUNCTION BYTE_BCD_TO_ULINT : ULINT VAR_INPUT IN : BYTE; END_VAR RETURN; END_FUNCTION
+FUNCTION BCD_TO_ULINT : ULINT VAR_INPUT IN : BYTE; END_VAR RETURN; END_FUNCTION
 FUNCTION WORD_BCD_TO_USINT : USINT VAR_INPUT IN : WORD; END_VAR RETURN; END_FUNCTION
+FUNCTION BCD_TO_USINT : USINT VAR_INPUT IN : WORD; END_VAR RETURN; END_FUNCTION
 FUNCTION WORD_BCD_TO_UINT : UINT VAR_INPUT IN : WORD; END_VAR RETURN; END_FUNCTION
+FUNCTION BCD_TO_UINT : UINT VAR_INPUT IN : WORD; END_VAR RETURN; END_FUNCTION
 FUNCTION WORD_BCD_TO_UDINT : UDINT VAR_INPUT IN : WORD; END_VAR RETURN; END_FUNCTION
+FUNCTION BCD_TO_UDINT : UDINT VAR_INPUT IN : WORD; END_VAR RETURN; END_FUNCTION
 FUNCTION WORD_BCD_TO_ULINT : ULINT VAR_INPUT IN : WORD; END_VAR RETURN; END_FUNCTION
+FUNCTION BCD_TO_ULINT : ULINT VAR_INPUT IN : WORD; END_VAR RETURN; END_FUNCTION
 FUNCTION DWORD_BCD_TO_USINT : USINT VAR_INPUT IN : DWORD; END_VAR RETURN; END_FUNCTION
+FUNCTION BCD_TO_USINT : USINT VAR_INPUT IN : DWORD; END_VAR RETURN; END_FUNCTION
 FUNCTION DWORD_BCD_TO_UINT : UINT VAR_INPUT IN : DWORD; END_VAR RETURN; END_FUNCTION
+FUNCTION BCD_TO_UINT : UINT VAR_INPUT IN : DWORD; END_VAR RETURN; END_FUNCTION
 FUNCTION DWORD_BCD_TO_UDINT : UDINT VAR_INPUT IN : DWORD; END_VAR RETURN; END_FUNCTION
+FUNCTION BCD_TO_UDINT : UDINT VAR_INPUT IN : DWORD; END_VAR RETURN; END_FUNCTION
 FUNCTION DWORD_BCD_TO_ULINT : ULINT VAR_INPUT IN : DWORD; END_VAR RETURN; END_FUNCTION
+FUNCTION BCD_TO_ULINT : ULINT VAR_INPUT IN : DWORD; END_VAR RETURN; END_FUNCTION
 FUNCTION LWORD_BCD_TO_USINT : USINT VAR_INPUT IN : LWORD; END_VAR RETURN; END_FUNCTION
+FUNCTION BCD_TO_USINT : USINT VAR_INPUT IN : LWORD; END_VAR RETURN; END_FUNCTION
 FUNCTION LWORD_BCD_TO_UINT : UINT VAR_INPUT IN : LWORD; END_VAR RETURN; END_FUNCTION
+FUNCTION BCD_TO_UINT : UINT VAR_INPUT IN : LWORD; END_VAR RETURN; END_FUNCTION
 FUNCTION LWORD_BCD_TO_UDINT : UDINT VAR_INPUT IN : LWORD; END_VAR RETURN; END_FUNCTION
+FUNCTION BCD_TO_UDINT : UDINT VAR_INPUT IN : LWORD; END_VAR RETURN; END_FUNCTION
 FUNCTION LWORD_BCD_TO_ULINT : ULINT VAR_INPUT IN : LWORD; END_VAR RETURN; END_FUNCTION
+FUNCTION BCD_TO_ULINT : ULINT VAR_INPUT IN : LWORD; END_VAR RETURN; END_FUNCTION
 FUNCTION ABS_REAL : REAL VAR_INPUT IN : REAL; END_VAR RETURN; END_FUNCTION
 FUNCTION ABS : REAL VAR_INPUT IN : REAL; END_VAR RETURN; END_FUNCTION
 FUNCTION ABS_LREAL : LREAL VAR_INPUT IN : LREAL; END_VAR RETURN; END_FUNCTION
--- a/stage1_2/iec_flex.ll	Thu Jan 03 17:04:04 2013 +0000
+++ b/stage1_2/iec_flex.ll	Thu Jan 03 18:23:07 2013 +0000
@@ -522,7 +522,7 @@
 
 /* Any other pragma... */
 
-pragma "{"[^}]*"}"
+pragma "{"[^}]*"}"|"{{"([^}]|"}"[^}])*"}}"
 
 /* NOTE: this seemingly unnecessary complex definition is required
  *       to be able to eat up comments such as:
@@ -859,13 +859,15 @@
 	/* Any other pragma we find, we just pass it up to the syntax parser...   */
 	/* Note that the <body_state> state is exclusive, so we have to include it here too. */
 {pragma}	{/* return the pragmma without the enclosing '{' and '}' */
-		 yytext[strlen(yytext)-1] = '\0';
-		 yylval.ID=strdup(yytext+1);
+         int cut = yytext[1]=='{'?2:1;
+		 yytext[strlen(yytext)-cut] = '\0';
+		 yylval.ID=strdup(yytext+cut);
 		 return pragma_token;
 		}
 <body_state>{pragma} {/* return the pragmma without the enclosing '{' and '}' */
-		 yytext[strlen(yytext)-1] = '\0';
-		 yylval.ID=strdup(yytext+1);
+		 int cut = yytext[1]=='{'?2:1;
+         yytext[strlen(yytext)-cut] = '\0';
+		 yylval.ID=strdup(yytext+cut);
 		 return pragma_token;
 		}
 
--- a/stage4/generate_c/generate_c.cc	Thu Jan 03 17:04:04 2013 +0000
+++ b/stage4/generate_c/generate_c.cc	Thu Jan 03 18:23:07 2013 +0000
@@ -109,31 +109,38 @@
 /* Variable declaration symbol for accessor macros */
 #define DECLARE_VAR "__DECLARE_VAR"
 #define DECLARE_GLOBAL "__DECLARE_GLOBAL"
+#define DECLARE_GLOBAL_FB "__DECLARE_GLOBAL_FB"
 #define DECLARE_GLOBAL_LOCATION "__DECLARE_GLOBAL_LOCATION"
 #define DECLARE_GLOBAL_LOCATED "__DECLARE_GLOBAL_LOCATED"
 #define DECLARE_EXTERNAL "__DECLARE_EXTERNAL"
+#define DECLARE_EXTERNAL_FB "__DECLARE_EXTERNAL_FB"
 #define DECLARE_LOCATED "__DECLARE_LOCATED"
 #define DECLARE_GLOBAL_PROTOTYPE "__DECLARE_GLOBAL_PROTOTYPE"
 
 /* Variable declaration symbol for accessor macros */
 #define INIT_VAR "__INIT_VAR"
 #define INIT_GLOBAL "__INIT_GLOBAL"
+#define INIT_GLOBAL_FB "__INIT_GLOBAL_FB"
 #define INIT_GLOBAL_LOCATED "__INIT_GLOBAL_LOCATED"
 #define INIT_EXTERNAL "__INIT_EXTERNAL"
+#define INIT_EXTERNAL_FB "__INIT_EXTERNAL_FB"
 #define INIT_LOCATED "__INIT_LOCATED"
 #define INIT_LOCATED_VALUE "__INIT_LOCATED_VALUE"
 
 /* Variable getter symbol for accessor macros */
 #define GET_VAR "__GET_VAR"
 #define GET_EXTERNAL "__GET_EXTERNAL"
+#define GET_EXTERNAL_FB "__GET_EXTERNAL_FB"
 #define GET_LOCATED "__GET_LOCATED"
 #define GET_VAR_BY_REF "__GET_VAR_BY_REF"
 #define GET_EXTERNAL_BY_REF "__GET_EXTERNAL_BY_REF"
+#define GET_EXTERNAL_FB_BY_REF "__GET_EXTERNAL_FB_BY_REF"
 #define GET_LOCATED_BY_REF "__GET_LOCATED_BY_REF"
 
 /* Variable setter symbol for accessor macros */
 #define SET_VAR "__SET_VAR"
 #define SET_EXTERNAL "__SET_EXTERNAL"
+#define SET_EXTERNAL_FB "__SET_EXTERNAL_FB"
 #define SET_LOCATED "__SET_LOCATED"
 
 /* Variable initial value symbol for accessor macros */
@@ -592,7 +599,7 @@
     };
     virtual ~generate_c_datatypes_c(void) {
       while (!inline_array_defined.empty()) {
-    	inline_array_defined.erase(inline_array_defined.begin());
+        inline_array_defined.erase(inline_array_defined.begin());
       }
     }
 
@@ -626,19 +633,19 @@
 
     #define HANDLE_ELEMENTARY_DATA_TYPE(datatype_symbol, datatype_name)\
     void *visit(datatype_symbol *symbol) {\
-	  switch (current_mode) {\
-		case arrayname_im:\
-		  current_array_name += datatype_name;\
-		  break;\
+      switch (current_mode) {\
+        case arrayname_im:\
+          current_array_name += datatype_name;\
+          break;\
         case arraydeclaration_im:\
           s4o_incl.print(datatype_name);\
           break;\
-		default:\
-		  return generate_c_base_c::visit(symbol);\
-		  break;\
-	  }\
-	  return NULL;\
-	}
+        default:\
+          return generate_c_base_c::visit(symbol);\
+          break;\
+      }\
+      return NULL;\
+    }
 
     HANDLE_ELEMENTARY_DATA_TYPE(time_type_name_c, "TIME")
     HANDLE_ELEMENTARY_DATA_TYPE(bool_type_name_c, "BOOL")
@@ -663,26 +670,76 @@
     HANDLE_ELEMENTARY_DATA_TYPE(wstring_type_name_c, "WSTRING")
 
     HANDLE_ELEMENTARY_DATA_TYPE(safetime_type_name_c, "TIME")
-	HANDLE_ELEMENTARY_DATA_TYPE(safebool_type_name_c, "BOOL")
-	HANDLE_ELEMENTARY_DATA_TYPE(safesint_type_name_c, "SINT")
-	HANDLE_ELEMENTARY_DATA_TYPE(safeint_type_name_c, "INT")
-	HANDLE_ELEMENTARY_DATA_TYPE(safedint_type_name_c, "DINT")
-	HANDLE_ELEMENTARY_DATA_TYPE(safelint_type_name_c, "LINT")
-	HANDLE_ELEMENTARY_DATA_TYPE(safeusint_type_name_c, "USINT")
-	HANDLE_ELEMENTARY_DATA_TYPE(safeuint_type_name_c, "UINT")
-	HANDLE_ELEMENTARY_DATA_TYPE(safeudint_type_name_c, "UDINT")
-	HANDLE_ELEMENTARY_DATA_TYPE(safeulint_type_name_c, "ULINT")
-	HANDLE_ELEMENTARY_DATA_TYPE(safereal_type_name_c, "REAL")
-	HANDLE_ELEMENTARY_DATA_TYPE(safelreal_type_name_c, "LREAL")
-	HANDLE_ELEMENTARY_DATA_TYPE(safedate_type_name_c, "DATE")
-	HANDLE_ELEMENTARY_DATA_TYPE(safetod_type_name_c, "TOD")
-	HANDLE_ELEMENTARY_DATA_TYPE(safedt_type_name_c, "DT")
-	HANDLE_ELEMENTARY_DATA_TYPE(safebyte_type_name_c, "BYTE")
-	HANDLE_ELEMENTARY_DATA_TYPE(safeword_type_name_c, "WORD")
-	HANDLE_ELEMENTARY_DATA_TYPE(safedword_type_name_c, "DWORD")
-	HANDLE_ELEMENTARY_DATA_TYPE(safelword_type_name_c, "LWORD")
-	HANDLE_ELEMENTARY_DATA_TYPE(safestring_type_name_c, "STRING")
-	HANDLE_ELEMENTARY_DATA_TYPE(safewstring_type_name_c, "WSTRING")
+    HANDLE_ELEMENTARY_DATA_TYPE(safebool_type_name_c, "BOOL")
+    HANDLE_ELEMENTARY_DATA_TYPE(safesint_type_name_c, "SINT")
+    HANDLE_ELEMENTARY_DATA_TYPE(safeint_type_name_c, "INT")
+    HANDLE_ELEMENTARY_DATA_TYPE(safedint_type_name_c, "DINT")
+    HANDLE_ELEMENTARY_DATA_TYPE(safelint_type_name_c, "LINT")
+    HANDLE_ELEMENTARY_DATA_TYPE(safeusint_type_name_c, "USINT")
+    HANDLE_ELEMENTARY_DATA_TYPE(safeuint_type_name_c, "UINT")
+    HANDLE_ELEMENTARY_DATA_TYPE(safeudint_type_name_c, "UDINT")
+    HANDLE_ELEMENTARY_DATA_TYPE(safeulint_type_name_c, "ULINT")
+    HANDLE_ELEMENTARY_DATA_TYPE(safereal_type_name_c, "REAL")
+    HANDLE_ELEMENTARY_DATA_TYPE(safelreal_type_name_c, "LREAL")
+    HANDLE_ELEMENTARY_DATA_TYPE(safedate_type_name_c, "DATE")
+    HANDLE_ELEMENTARY_DATA_TYPE(safetod_type_name_c, "TOD")
+    HANDLE_ELEMENTARY_DATA_TYPE(safedt_type_name_c, "DT")
+    HANDLE_ELEMENTARY_DATA_TYPE(safebyte_type_name_c, "BYTE")
+    HANDLE_ELEMENTARY_DATA_TYPE(safeword_type_name_c, "WORD")
+    HANDLE_ELEMENTARY_DATA_TYPE(safedword_type_name_c, "DWORD")
+    HANDLE_ELEMENTARY_DATA_TYPE(safelword_type_name_c, "LWORD")
+    HANDLE_ELEMENTARY_DATA_TYPE(safestring_type_name_c, "STRING")
+    HANDLE_ELEMENTARY_DATA_TYPE(safewstring_type_name_c, "WSTRING")
+
+    /***********************************/
+    /* B 1.3.2 - Generic Data Types    */
+    /***********************************/
+
+    /*  structure_type_name ':' structure_specification */
+    //SYM_REF2(structure_type_declaration_c, structure_type_name, structure_specification)
+    void *visit(structure_type_declaration_c *symbol) {
+      current_mode = arraydeclaration_im;
+      symbol->structure_specification->accept(*this);
+      current_mode = arrayname_im;
+      generate_c_typedecl_c::visit(symbol);
+      current_mode = none_im;
+      return NULL;
+    }
+
+    /* helper symbol for structure_declaration */
+    /* structure_declaration:  STRUCT structure_element_declaration_list END_STRUCT */
+    /* structure_element_declaration_list structure_element_declaration ';' */
+    //SYM_LIST(structure_element_declaration_list_c)
+    void *visit(structure_element_declaration_list_c *symbol) {
+      switch (current_mode) {
+        case arraydeclaration_im:
+          iterator_visitor_c::visit(symbol);
+          break;
+        default:
+          generate_c_typedecl_c::visit(symbol);
+          break;
+      }
+      return NULL;
+    }
+
+    /*  structure_element_name ':' spec_init */
+    //SYM_REF2(structure_element_declaration_c, structure_element_name, spec_init)
+    void *visit(structure_element_declaration_c *symbol) {
+      switch (current_mode) {
+        case arraydeclaration_im:
+          {
+            array_spec_init_c *spec_init = dynamic_cast<array_spec_init_c*>(symbol->spec_init);
+            if (spec_init != NULL) {
+              symbol->spec_init->accept(*this);
+            }
+          }
+          break;
+        default:
+          generate_c_typedecl_c::visit(symbol);
+          break;
+      }
+      return NULL;
+    }
 
     /******************************************/
     /* B 1.4.3 - Declaration & Initialization */
@@ -712,7 +769,7 @@
     /*  var1_list ':' array_spec_init */
     // SYM_REF2(array_var_init_decl_c, var1_list, array_spec_init)
     void *visit(array_var_init_decl_c *symbol) {
-      current_mode = arrayname_im;
+      current_mode = arraydeclaration_im;
       symbol->array_spec_init->accept(*this);
       current_mode = none_im;
       return NULL;
@@ -722,15 +779,16 @@
     /* array_initialization may be NULL ! */
     void *visit(array_spec_init_c *symbol) {
       switch (current_mode) {
-    	case arrayname_im:
-    	  {
-    	    array_specification_c *specification = dynamic_cast<array_specification_c*>(symbol->array_specification);
+        case arraydeclaration_im:
+        case arrayname_im:
+          {
+            array_specification_c *specification = dynamic_cast<array_specification_c*>(symbol->array_specification);
             if (specification != NULL)
               symbol->array_specification->accept(*this);
           }
           break;
-    	default:
-    	  return generate_c_typedecl_c::visit(symbol);
+        default:
+          return generate_c_typedecl_c::visit(symbol);
           break;
       }
       return NULL;
@@ -739,17 +797,17 @@
     /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
     void *visit(array_specification_c *symbol) {
       switch (current_mode) {
-        case arrayname_im:
+        case arraydeclaration_im:
           {
+            current_mode = arrayname_im;
             std::map<std::string,int>::iterator definition;
             current_array_name = "__";
             symbol->non_generic_type_name->accept(*this);
             symbol->array_subrange_list->accept(*this);
+            current_mode = arraydeclaration_im;
 
             definition = inline_array_defined.find(current_array_name);
             if (definition == inline_array_defined.end()) {
-              current_mode = arraydeclaration_im;
-
               s4o_incl.print("__DECLARE_ARRAY_TYPE(");
               s4o_incl.print(current_array_name);
               s4o_incl.print(",");
@@ -762,6 +820,15 @@
             }
           }
           break;
+        case arrayname_im:
+          {
+              std::map<std::string,int>::iterator definition;
+              current_array_name = "__";
+              symbol->non_generic_type_name->accept(*this);
+              symbol->array_subrange_list->accept(*this);
+              s4o_incl.print(current_array_name);
+          }
+          break;
         default:
           return generate_c_typedecl_c::visit(symbol);
           break;
@@ -821,8 +888,8 @@
     //SYM_REF2(array_var_declaration_c, var1_list, array_specification)
     void *visit(array_var_declaration_c *symbol) {
       array_specification_c *specification = dynamic_cast<array_specification_c*>(symbol->array_specification);
-	  if (specification != NULL) {
-        current_mode = arrayname_im;
+      if (specification != NULL) {
+        current_mode = arraydeclaration_im;
         symbol->array_specification->accept(*this);
         current_mode = none_im;
       }
@@ -863,9 +930,9 @@
     void *visit(located_var_decl_c *symbol) {
       array_spec_init_c* array_spec_init = dynamic_cast<array_spec_init_c*>(symbol->located_var_spec_init);
       if (array_spec_init != NULL) {
-    	current_mode = arrayname_im;
-    	symbol->located_var_spec_init->accept(*this);
-    	current_mode = none_im;
+        current_mode = arraydeclaration_im;
+        symbol->located_var_spec_init->accept(*this);
+        current_mode = none_im;
       }
       return NULL;
     }
@@ -883,7 +950,7 @@
     void *visit(external_declaration_c *symbol) {
       array_specification_c* array_specification = dynamic_cast<array_specification_c*>(symbol->specification);
       if (array_specification != NULL) {
-        current_mode = arrayname_im;
+        current_mode = arraydeclaration_im;
         symbol->specification->accept(*this);
         current_mode = none_im;
       }
@@ -904,7 +971,7 @@
     void *visit(global_var_decl_c *symbol) {
       array_spec_init_c* array_spec_init = dynamic_cast<array_spec_init_c*>(symbol->type_specification);
       if (array_spec_init != NULL) {
-        current_mode = arrayname_im;
+        current_mode = arraydeclaration_im;
         symbol->type_specification->accept(*this);
         current_mode = none_im;
       }
@@ -962,8 +1029,7 @@
        * To work around this we introduce the useless goto.
        */
       s4o.print("\n");
-      s4o.print(s4o.indent_spaces);
-      s4o.print("/* to humour the compiler, we insert a goto */\n");
+      /* to humour the compiler, we insert a goto */
       s4o.print(s4o.indent_spaces);
       s4o.print("goto ");
       s4o.print(END_LABEL);
--- a/stage4/generate_c/generate_c_base.cc	Thu Jan 03 17:04:04 2013 +0000
+++ b/stage4/generate_c/generate_c_base.cc	Thu Jan 03 18:23:07 2013 +0000
@@ -259,7 +259,19 @@
     void *visit(disable_code_generation_pragma_c * symbol)  {s4o.disable_output(); return NULL;} 
 
     /* Do not use print_token() as it will change everything into uppercase */
-    void *visit(pragma_c *symbol) {return s4o.print(symbol->value);}
+    void *visit(pragma_c *symbol) {
+        s4o.print(s4o.indent_spaces);
+        s4o.print("#define GetFbVar(var,...) __GET_VAR(data__->var,__VA_ARGS__)\n");
+        s4o.print(s4o.indent_spaces);
+        s4o.print("#define SetFbVar(var,val,...) __SET_VAR(data__->,var,val,__VA_ARGS__)\n");
+        s4o.print(symbol->value);
+        s4o.print("\n");
+        s4o.print(s4o.indent_spaces);
+        s4o.print("#undef GetFbVar\n");
+        s4o.print(s4o.indent_spaces);
+        s4o.print("#undef SetFbVar\n");
+        return NULL;
+    }
 
 
 /***************************/
--- a/stage4/generate_c/generate_c_il.cc	Thu Jan 03 17:04:04 2013 +0000
+++ b/stage4/generate_c/generate_c_il.cc	Thu Jan 03 18:23:07 2013 +0000
@@ -366,20 +366,28 @@
     void *print_getter(symbol_c *symbol) {
       unsigned int vartype = search_var_instance_decl->get_vartype(symbol);
       if (wanted_variablegeneration == fparam_output_vg) {
-      	if (vartype == search_var_instance_decl_c::external_vt)
-          s4o.print(GET_EXTERNAL_BY_REF);
+        if (vartype == search_var_instance_decl_c::external_vt) {
+          if (search_var_instance_decl->type_is_fb(symbol))
+            s4o.print(GET_EXTERNAL_FB_BY_REF);
+          else
+            s4o.print(GET_EXTERNAL_BY_REF);
+        }
         else if (vartype == search_var_instance_decl_c::located_vt)
           s4o.print(GET_LOCATED_BY_REF);
         else
           s4o.print(GET_VAR_BY_REF);
       }
       else {
-    	if (vartype == search_var_instance_decl_c::external_vt)
-    	  s4o.print(GET_EXTERNAL);
-    	else if (vartype == search_var_instance_decl_c::located_vt)
-    	  s4o.print(GET_LOCATED);
-    	else
-    	  s4o.print(GET_VAR);
+        if (vartype == search_var_instance_decl_c::external_vt) {
+          if (search_var_instance_decl->type_is_fb(symbol))
+            s4o.print(GET_EXTERNAL_FB);
+          else
+            s4o.print(GET_EXTERNAL);
+        }
+        else if (vartype == search_var_instance_decl_c::located_vt)
+          s4o.print(GET_LOCATED);
+        else
+          s4o.print(GET_VAR);
       }
       s4o.print("(");
 
@@ -396,25 +404,33 @@
     }
 
     void *print_setter(symbol_c* symbol,
-    		symbol_c* type,
-    		symbol_c* value,
-    		symbol_c* fb_symbol = NULL,
-    		symbol_c* fb_value = NULL,
-    		bool negative = false) {
-
-      bool type_is_complex = false;
+            symbol_c* type,
+            symbol_c* value,
+            symbol_c* fb_symbol = NULL,
+            symbol_c* fb_value = NULL,
+            bool negative = false) {
+
+      bool type_is_complex = search_var_instance_decl->type_is_complex(symbol);
       if (fb_symbol == NULL) {
         unsigned int vartype = search_var_instance_decl->get_vartype(symbol);
-        type_is_complex = search_var_instance_decl->type_is_complex(symbol);
-        if (vartype == search_var_instance_decl_c::external_vt)
-          s4o.print(SET_EXTERNAL);
+        if (vartype == search_var_instance_decl_c::external_vt) {
+          if (search_var_instance_decl->type_is_fb(symbol))
+            s4o.print(SET_EXTERNAL_FB);
+          else
+            s4o.print(SET_EXTERNAL);
+        }
         else if (vartype == search_var_instance_decl_c::located_vt)
           s4o.print(SET_LOCATED);
         else
           s4o.print(SET_VAR);
       }
-      else
-        s4o.print(SET_VAR);
+      else {
+        unsigned int vartype = search_var_instance_decl->get_vartype(fb_symbol);
+        if (vartype == search_var_instance_decl_c::external_vt)
+          s4o.print(SET_EXTERNAL_FB);
+        else
+          s4o.print(SET_VAR);
+      }
       s4o.print("(");
 
       if (fb_symbol != NULL) {
@@ -431,9 +447,9 @@
       s4o.print(",");
       if (negative) {
 	    if (get_datatype_info_c::is_BOOL_compatible(this->current_operand->datatype))
-		  s4o.print("!");
-	    else
-		  s4o.print("~");
+          s4o.print("!");
+        else
+          s4o.print("~");
       }
       wanted_variablegeneration = expression_vg;
       print_check_function(type, value, fb_value);
@@ -495,10 +511,10 @@
       generate_c_base_c::visit(symbol);
       break;
     case complextype_suffix_vg:
-	  break;
+      break;
     default:
       if (this->is_variable_prefix_null()) {
-	    vartype = search_var_instance_decl->get_vartype(symbol);
+        vartype = search_var_instance_decl->get_vartype(symbol);
         if (wanted_variablegeneration == fparam_output_vg) {
           s4o.print("&(");
           generate_c_base_c::visit(symbol);
@@ -525,14 +541,14 @@
   if (strlen(symbol->value) == 0) ERROR;
   if (this->is_variable_prefix_null()) {
     if (wanted_variablegeneration != fparam_output_vg)
-	  s4o.print("*(");
+      s4o.print("*(");
   }
   else {
     switch (wanted_variablegeneration) {
       case expression_vg:
-  	    s4o.print(GET_LOCATED);
-  	    s4o.print("(");
-  	    break;
+        s4o.print(GET_LOCATED);
+        s4o.print("(");
+        break;
       case fparam_output_vg:
         s4o.print(GET_LOCATED_BY_REF);
         s4o.print("(");
@@ -544,7 +560,7 @@
   this->print_variable_prefix();
   s4o.printlocation(symbol->value + 1);
   if ((this->is_variable_prefix_null() && wanted_variablegeneration != fparam_output_vg) ||
-	  wanted_variablegeneration != assignment_vg)
+      wanted_variablegeneration != assignment_vg)
     s4o.print(")");
   return NULL;
 }
@@ -567,25 +583,25 @@
       }
       break;
     case complextype_suffix_vg:
-	  symbol->record_variable->accept(*this);
-	  if (type_is_complex) {
-		s4o.print(".");
-		symbol->field_selector->accept(*this);
-	  }
-	  break;
-	case assignment_vg:
-	  symbol->record_variable->accept(*this);
-	  s4o.print(".");
-	  symbol->field_selector->accept(*this);
-	  break;
+      symbol->record_variable->accept(*this);
+      if (type_is_complex) {
+        s4o.print(".");
+        symbol->field_selector->accept(*this);
+      }
+      break;
+    case assignment_vg:
+      symbol->record_variable->accept(*this);
+      s4o.print(".");
+      symbol->field_selector->accept(*this);
+      break;
     default:
       if (this->is_variable_prefix_null()) {
-    	symbol->record_variable->accept(*this);
-    	s4o.print(".");
-    	symbol->field_selector->accept(*this);
+        symbol->record_variable->accept(*this);
+        s4o.print(".");
+        symbol->field_selector->accept(*this);
       }
       else
-    	print_getter(symbol);
+        print_getter(symbol);
       break;
   }
   return NULL;
@@ -623,7 +639,7 @@
         current_array_type = NULL;
       }
       else
-    	print_getter(symbol);
+        print_getter(symbol);
       break;
   }
   return NULL;
@@ -634,9 +650,9 @@
   array_dimension_iterator_c* array_dimension_iterator = new array_dimension_iterator_c(current_array_type);
   for (int i =  0; i < symbol->n; i++) {
     symbol_c* dimension = array_dimension_iterator->next();
-	if (dimension == NULL) ERROR;
-
-	s4o.print("[(");
+    if (dimension == NULL) ERROR;
+
+    s4o.print("[(");
     symbol->elements[i]->accept(*this);
     s4o.print(") - (");
     dimension->accept(*this);
@@ -860,7 +876,7 @@
     s4o.print(")");
   }
   if (function_type_suffix != NULL) {
-  	function_type_suffix = default_literal_type(function_type_suffix);
+    function_type_suffix = default_literal_type(function_type_suffix);
   }
   if (has_output_params) {
     fcall_number++;
@@ -885,7 +901,7 @@
             print_function_parameter_data_types_c overloaded_func_suf(&s4o);
             f_decl->accept(overloaded_func_suf);
           }
-    }	  
+    }
     if (function_type_suffix != NULL)
       function_type_suffix->accept(*this);
   }
@@ -1051,13 +1067,13 @@
     if (param_value != NULL)
       if ((param_direction == function_param_iterator_c::direction_in) ||
           (param_direction == function_param_iterator_c::direction_inout)) {
-    	if (this->is_variable_prefix_null()) {
-    	  symbol->fb_name->accept(*this);
+        if (this->is_variable_prefix_null()) {
+          symbol->fb_name->accept(*this);
           s4o.print(".");
           param_name->accept(*this);
           s4o.print(" = ");
           print_check_function(param_type, param_value);
-    	}
+        }
         else {
           print_setter(param_name, param_type, param_value, symbol->fb_name);
         }
@@ -1068,7 +1084,9 @@
   /* now call the function... */
   function_block_type_name->accept(*this);
   s4o.print(FB_FUNCTION_SUFFIX);
-  s4o.print("(&");
+  s4o.print("(");
+  if (search_var_instance_decl->get_vartype(symbol->fb_name) != search_var_instance_decl_c::external_vt)
+    s4o.print("&");
   print_variable_prefix();
   symbol->fb_name->accept(*this);
   s4o.print(")");
@@ -1099,12 +1117,12 @@
         s4o.print(";\n" + s4o.indent_spaces);
         if (this->is_variable_prefix_null()) {
           param_value->accept(*this);
-		  s4o.print(" = ");
-		  print_check_function(param_type, param_name, symbol->fb_name);
-		}
-		else {
-		  print_setter(param_value, param_type, param_name, NULL, symbol->fb_name);
-		}
+          s4o.print(" = ");
+          print_check_function(param_type, param_name, symbol->fb_name);
+        }
+        else {
+          print_setter(param_value, param_type, param_name, NULL, symbol->fb_name);
+        }
       }
   } /* for(...) */
 
@@ -1250,7 +1268,7 @@
     s4o.print(")");
   }
   if (function_type_suffix != NULL) {
-  	function_type_suffix = default_literal_type(function_type_suffix);
+    function_type_suffix = default_literal_type(function_type_suffix);
   }
   if (has_output_params) {
     fcall_number++;
@@ -1420,7 +1438,7 @@
 
 
 // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
-void *visit(il_simple_instruction_c *symbol)    {
+void *visit(il_simple_instruction_c *symbol) {
   /* all previous IL instructions should have the same datatype (checked in stage3), so we get the datatype from the first previous IL instruction we find */
   implicit_variable_current.datatype = (symbol->prev_il_instruction.empty())? NULL : symbol->prev_il_instruction[0]->datatype;
   implicit_variable_result .datatype = symbol->datatype;
@@ -1511,7 +1529,7 @@
 }
 
 
-void *visit(S_operator_c *symbol)	{
+void *visit(S_operator_c *symbol) {
   if (wanted_variablegeneration != expression_vg) {
     s4o.print("LD");
     return NULL;
@@ -1533,7 +1551,7 @@
 }
 
 
-void *visit(R_operator_c *symbol)	{
+void *visit(R_operator_c *symbol) {
   if (wanted_variablegeneration != expression_vg) {
     s4o.print("LD");
     return NULL;
@@ -1565,66 +1583,66 @@
 void *visit( IN_operator_c *symbol)	{return XXX_CAL_operator( "IN", this->current_operand);}
 void *visit( PT_operator_c *symbol)	{return XXX_CAL_operator( "PT", this->current_operand);}
 
-void *visit(AND_operator_c *symbol)	{
+void *visit(AND_operator_c *symbol) {
   if (!get_datatype_info_c::is_ANY_BIT_compatible(symbol->datatype)) ERROR;
   XXX_operator(&(this->implicit_variable_result), " &= ", this->current_operand);
   return NULL;
 }
 
-void *visit(OR_operator_c *symbol)	{
+void *visit(OR_operator_c *symbol) {
   if (!get_datatype_info_c::is_ANY_BIT_compatible(symbol->datatype)) ERROR;
   XXX_operator(&(this->implicit_variable_result), " |= ", this->current_operand);
   return NULL;
 }
 
-void *visit(XOR_operator_c *symbol)	{
+void *visit(XOR_operator_c *symbol) {
   if (!get_datatype_info_c::is_ANY_BIT_compatible(symbol->datatype)) ERROR;
   // '^' is a bit by bit exclusive OR !! Also seems to work with boolean types!
   XXX_operator(&(this->implicit_variable_result), " ^= ", this->current_operand);
   return NULL;
 }
 
-void *visit(ANDN_operator_c *symbol)	{
+void *visit(ANDN_operator_c *symbol) {
   if (!get_datatype_info_c::is_ANY_BIT_compatible(symbol->datatype)) ERROR;
   XXX_operator(&(this->implicit_variable_result), get_datatype_info_c::is_BOOL_compatible(this->current_operand->datatype)?" &= !":" &= ~", this->current_operand);
   return NULL;
 }
 
-void *visit(ORN_operator_c *symbol)	{
+void *visit(ORN_operator_c *symbol) {
   if (!get_datatype_info_c::is_ANY_BIT_compatible(symbol->datatype)) ERROR;
   XXX_operator(&(this->implicit_variable_result), get_datatype_info_c::is_BOOL_compatible(this->current_operand->datatype)?" |= !":" |= ~", this->current_operand);
   return NULL;
 }
 
-void *visit(XORN_operator_c *symbol)	{
+void *visit(XORN_operator_c *symbol) {
   if (!get_datatype_info_c::is_ANY_BIT_compatible(symbol->datatype)) ERROR;
   // bit by bit exclusive OR !! Also seems to work with boolean types!
   XXX_operator(&(this->implicit_variable_result), get_datatype_info_c::is_BOOL_compatible(this->current_operand->datatype)?" ^= !":" ^= ~", this->current_operand);
   return NULL;
 }
 
-void *visit(ADD_operator_c *symbol)	{
+void *visit(ADD_operator_c *symbol) {
   if (get_datatype_info_c::is_TIME_compatible(symbol->datatype) || get_datatype_info_c::is_ANY_DATE_compatible  (symbol->datatype)) 
         XXX_function(&(this->implicit_variable_result), "__time_add", &(this->implicit_variable_current), this->current_operand);
   else  XXX_operator(&(this->implicit_variable_result), " += ", this->current_operand);
   return NULL;
 }
 
-void *visit(SUB_operator_c *symbol)	{
+void *visit(SUB_operator_c *symbol) {
   if (get_datatype_info_c::is_TIME_compatible(symbol->datatype) || get_datatype_info_c::is_ANY_DATE_compatible  (symbol->datatype))
         XXX_function(&(this->implicit_variable_result), "__time_sub", &(this->implicit_variable_current), this->current_operand);
   else  XXX_operator(&(this->implicit_variable_result), " -= ", this->current_operand);
   return NULL;
 }
 
-void *visit(MUL_operator_c *symbol)	{
+void *visit(MUL_operator_c *symbol) {
   if (get_datatype_info_c::is_TIME_compatible(symbol->datatype))
         XXX_function(&(this->implicit_variable_result), "__time_mul", &(this->implicit_variable_current), this->current_operand);
   else  XXX_operator(&(this->implicit_variable_result), " *= ", this->current_operand);
   return NULL;
 }
 
-void *visit(DIV_operator_c *symbol)	{
+void *visit(DIV_operator_c *symbol) {
   if (get_datatype_info_c::is_TIME_compatible(symbol->datatype))
         XXX_function(&(this->implicit_variable_result), "__time_div", &(this->implicit_variable_current), this->current_operand);
   else  XXX_operator(&(this->implicit_variable_result), " /= ", this->current_operand);
@@ -1685,7 +1703,7 @@
 }
 
 //SYM_REF0(JMP_operator_c)
-void *visit(JMP_operator_c *symbol)	{
+void *visit(JMP_operator_c *symbol) {
   if (NULL == this->jump_label) ERROR;
   s4o.print("goto ");
   this->jump_label->accept(*this);
@@ -1693,7 +1711,7 @@
 }
 
 // SYM_REF0(JMPC_operator_c)
-void *visit(JMPC_operator_c *symbol)	{
+void *visit(JMPC_operator_c *symbol) {
   if (NULL == this->jump_label) ERROR;
   C_modifier();
   s4o.print("goto ");
@@ -1702,7 +1720,7 @@
 }
 
 // SYM_REF0(JMPCN_operator_c)
-void *visit(JMPCN_operator_c *symbol)	{
+void *visit(JMPCN_operator_c *symbol) {
   if (NULL == this->jump_label) ERROR;
   CN_modifier();
   s4o.print("goto ");
--- a/stage4/generate_c/generate_c_inlinefcall.cc	Thu Jan 03 17:04:04 2013 +0000
+++ b/stage4/generate_c/generate_c_inlinefcall.cc	Thu Jan 03 18:23:07 2013 +0000
@@ -37,29 +37,29 @@
     } variablegeneration_t;
 
   private:
-	 /* The result of the comparison IL operations (GT, EQ, LT, ...)
-	 * is a boolean variable.
-	 * This class keeps track of the current data type stored in the
-	 * il default variable. This is usually done by keeping a reference
-	 * to the data type of the last operand. Nevertheless, in the case of
-	 * the comparison IL operators, the data type of the result (a boolean)
-	 * is not the data type of the operand. We therefore need an object
-	 * of the boolean data type to keep as a reference of the current
-	 * data type.
-	 * The following object is it...
-	 */
-	bool_type_name_c bool_type;
-	lint_type_name_c lint_type;
-	lword_type_name_c lword_type;
-	lreal_type_name_c lreal_type;
+     /* The result of the comparison IL operations (GT, EQ, LT, ...)
+     * is a boolean variable.
+     * This class keeps track of the current data type stored in the
+     * il default variable. This is usually done by keeping a reference
+     * to the data type of the last operand. Nevertheless, in the case of
+     * the comparison IL operators, the data type of the result (a boolean)
+     * is not the data type of the operand. We therefore need an object
+     * of the boolean data type to keep as a reference of the current
+     * data type.
+     * The following object is it...
+     */
+    bool_type_name_c bool_type;
+    lint_type_name_c lint_type;
+    lword_type_name_c lword_type;
+    lreal_type_name_c lreal_type;
 
     /* The name of the IL default variable... */
-	#define IL_DEFVAR   VAR_LEADER "IL_DEFVAR"
-
-	/* The name of the variable used to pass the result of a
-	 * parenthesised instruction list to the immediately preceding
-	 * scope ...
-	 */
+    #define IL_DEFVAR   VAR_LEADER "IL_DEFVAR"
+
+    /* The name of the variable used to pass the result of a
+     * parenthesised instruction list to the immediately preceding
+     * scope ...
+     */
     #define IL_DEFVAR_BACK   VAR_LEADER "IL_DEFVAR_BACK"
     il_default_variable_c implicit_variable_current;
 
@@ -98,7 +98,7 @@
       function_call_iterator_c fc_iterator(symbol);
       symbol_c* function_call;
       while ((function_call = fc_iterator.next()) != NULL) {
-    	function_call->accept(*this);
+        function_call->accept(*this);
       }
     }
 
@@ -131,7 +131,7 @@
         s4o.print("__");
         print_function_parameter_data_types_c overloaded_func_suf(&s4o);
         f_decl->accept(overloaded_func_suf);
-      }	
+      }
       if (function_type_suffix) {
         function_type_suffix->accept(*this);
       }
@@ -180,8 +180,8 @@
       s4o.print(" = ");
       function_name->accept(*this);
       if (f_decl != NULL) {
-    	/* function being called is overloaded! */
-    	s4o.print("__");
+        /* function being called is overloaded! */
+        s4o.print("__");
         print_function_parameter_data_types_c overloaded_func_suf(&s4o);
         f_decl->accept(overloaded_func_suf);
       }
@@ -242,8 +242,12 @@
 
     void *print_getter(symbol_c *symbol) {
       unsigned int vartype = search_var_instance_decl->get_vartype(symbol);
-      if (vartype == search_var_instance_decl_c::external_vt)
-        s4o.print(GET_EXTERNAL);
+      if (vartype == search_var_instance_decl_c::external_vt) {
+        if (search_var_instance_decl->type_is_fb(symbol))
+          s4o.print(GET_EXTERNAL_FB);
+        else
+          s4o.print(GET_EXTERNAL);
+      }
       else if (vartype == search_var_instance_decl_c::located_vt)
         s4o.print(GET_LOCATED);
       else
@@ -265,8 +269,12 @@
                        symbol_c* type,
                        symbol_c* value) {
       unsigned int vartype = search_var_instance_decl->get_vartype(symbol);
-      if (vartype == search_var_instance_decl_c::external_vt)
-        s4o.print(SET_EXTERNAL);
+      if (vartype == search_var_instance_decl_c::external_vt) {
+        if (search_var_instance_decl->type_is_fb(symbol))
+          s4o.print(SET_EXTERNAL_FB);
+         else
+          s4o.print(SET_EXTERNAL);
+      }
       else if (vartype == search_var_instance_decl_c::located_vt)
         s4o.print(SET_LOCATED);
       else
@@ -335,8 +343,8 @@
           case complextype_base_vg:
             symbol->record_variable->accept(*this);
             if (!type_is_complex) {
-          	  s4o.print(".");
-          	  symbol->field_selector->accept(*this);
+                s4o.print(".");
+                symbol->field_selector->accept(*this);
             }
             break;
           case complextype_suffix_vg:
@@ -706,7 +714,7 @@
 
 
     // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
-    void *visit(il_simple_instruction_c *symbol)	{
+    void *visit(il_simple_instruction_c *symbol) {
       /* all previous IL instructions should have the same datatype (checked in stage3), so we get the datatype from the first previous IL instruction we find */
       implicit_variable_current.datatype = (symbol->prev_il_instruction.empty())? NULL : symbol->prev_il_instruction[0]->datatype;
       symbol->il_simple_instruction->accept(*this);
@@ -724,13 +732,13 @@
     /***********************/
 
     void *visit(statement_list_c *symbol) {
-	  function_call_iterator_c fc_iterator(symbol);
-	  symbol_c* function_call;
-	  while ((function_call = fc_iterator.next()) != NULL) {
-		function_call->accept(*this);
-	  }
-	  return NULL;
-	}
+      function_call_iterator_c fc_iterator(symbol);
+      symbol_c* function_call;
+      while ((function_call = fc_iterator.next()) != NULL) {
+        function_call->accept(*this);
+      }
+      return NULL;
+    }
 
     void *visit(function_invocation_c *symbol) {
       symbol_c* function_type_prefix = NULL;
@@ -861,43 +869,43 @@
       return NULL;
     }
 
-	/*********************************************/
-	/* B.1.6  Sequential function chart elements */
-	/*********************************************/
-
-	void *visit(initial_step_c *symbol) {
-		return NULL;
-	}
-
-	void *visit(step_c *symbol) {
-		return NULL;
-	}
-
-	void *visit(transition_c *symbol) {
-		return symbol->transition_condition->accept(*this);
-	}
-
-	void *visit(transition_condition_c *symbol) {
-		// Transition condition is in IL
-		if (symbol->transition_condition_il != NULL) {
-			symbol->transition_condition_il->accept(*this);
-		}
-
-		// Transition condition is in ST
-		if (symbol->transition_condition_st != NULL) {
-			function_call_iterator_c fc_iterator(symbol->transition_condition_st);
-			symbol_c* function_call;
-			while ((function_call = fc_iterator.next()) != NULL) {
-				function_call->accept(*this);
-			}
-		}
-
-		return NULL;
-	}
-
-	void *visit(action_c *symbol) {
-		return symbol->function_block_body->accept(*this);
-	}
+    /*********************************************/
+    /* B.1.6  Sequential function chart elements */
+    /*********************************************/
+
+    void *visit(initial_step_c *symbol) {
+        return NULL;
+    }
+
+    void *visit(step_c *symbol) {
+        return NULL;
+    }
+
+    void *visit(transition_c *symbol) {
+        return symbol->transition_condition->accept(*this);
+    }
+
+    void *visit(transition_condition_c *symbol) {
+        // Transition condition is in IL
+        if (symbol->transition_condition_il != NULL) {
+            symbol->transition_condition_il->accept(*this);
+        }
+
+        // Transition condition is in ST
+        if (symbol->transition_condition_st != NULL) {
+            function_call_iterator_c fc_iterator(symbol->transition_condition_st);
+            symbol_c* function_call;
+            while ((function_call = fc_iterator.next()) != NULL) {
+                function_call->accept(*this);
+            }
+        }
+
+        return NULL;
+    }
+
+    void *visit(action_c *symbol) {
+        return symbol->function_block_body->accept(*this);
+    }
 
 };  /* generate_c_inlinefcall_c */
 
--- a/stage4/generate_c/generate_c_sfc.cc	Thu Jan 03 17:04:04 2013 +0000
+++ b/stage4/generate_c/generate_c_sfc.cc	Thu Jan 03 18:23:07 2013 +0000
@@ -203,21 +203,22 @@
             current_step = symbol->step_name;
             s4o.print(s4o.indent_spaces + "{\n");
             s4o.indent_right();
-            s4o.print(s4o.indent_spaces + "char activated = ");
+            s4o.print(s4o.indent_spaces + "char activated, desactivated, active;\n");
+            s4o.print(s4o.indent_spaces + "activated = ");
             s4o.print(GET_VAR);
             s4o.print("(");
             print_step_argument(current_step, "state");
             s4o.print(") && !");
             print_step_argument(current_step, "prev_state");
             s4o.print(";\n");
-            s4o.print(s4o.indent_spaces + "char desactivated = !");
+            s4o.print(s4o.indent_spaces + "desactivated = !");
             s4o.print(GET_VAR);
             s4o.print("(");
             print_step_argument(current_step, "state");
             s4o.print(") && ");
             print_step_argument(current_step, "prev_state");
             s4o.print(";\n");
-            s4o.print(s4o.indent_spaces + "char active = ");
+            s4o.print(s4o.indent_spaces + "active = ");
             s4o.print(GET_VAR);
             s4o.print("(");
             print_step_argument(current_step, "state");
@@ -576,9 +577,10 @@
                 current_action->accept(*this);
                 s4o.print(",1);\n");
                 s4o.indent_left();
-                s4o.print("}\n");
+                s4o.print(s4o.indent_spaces + "}\n");
                 s4o.print(s4o.indent_spaces + "else if (active) {\n");
                 s4o.indent_right();
+                s4o.print(s4o.indent_spaces);
                 if (vartype == search_var_instance_decl_c::external_vt)
                   s4o.print(SET_EXTERNAL);
                 else if (vartype == search_var_instance_decl_c::located_vt)
@@ -610,7 +612,8 @@
             if (strcmp(qualifier, "SD") == 0 || strcmp(qualifier, "DS") == 0 || 
                 strcmp(qualifier, "SL") == 0) {
               if (strcmp(qualifier, "SL") == 0) {
-                print_action_argument(current_action, "reset_remaining_time");
+            	s4o.print(s4o.indent_spaces);
+            	print_action_argument(current_action, "reset_remaining_time");
               }
               else {
                 print_action_argument(current_action, "set_remaining_time");
@@ -622,9 +625,7 @@
             s4o.indent_left();
             s4o.print(s4o.indent_spaces + "}\n");
             if (strcmp(qualifier, "DS") == 0) {
-              s4o.print(s4o.indent_spaces + "if (");
-              s4o.print("desactivated");
-              s4o.print(") {\n");
+              s4o.print(s4o.indent_spaces + "if (desactivated) {\n");
               s4o.indent_right();
               s4o.print(s4o.indent_spaces);
               print_action_argument(current_action, "set_remaining_time");
@@ -699,7 +700,6 @@
       }
       
       s4o.print(s4o.indent_spaces +"INT i;\n");
-      s4o.print(s4o.indent_spaces +"BOOL transition;\n");
       s4o.print(s4o.indent_spaces +"TIME elapsed_time, current_time;\n\n");
       
       /* generate elapsed_time initializations */
--- a/stage4/generate_c/generate_c_st.cc	Thu Jan 03 17:04:04 2013 +0000
+++ b/stage4/generate_c/generate_c_st.cc	Thu Jan 03 18:23:07 2013 +0000
@@ -130,16 +130,24 @@
 void *print_getter(symbol_c *symbol) {
   unsigned int vartype = search_var_instance_decl->get_vartype(symbol);
   if (wanted_variablegeneration == fparam_output_vg) {
-    if (vartype == search_var_instance_decl_c::external_vt)
-      s4o.print(GET_EXTERNAL_BY_REF);
+    if (vartype == search_var_instance_decl_c::external_vt) {
+      if (search_var_instance_decl->type_is_fb(symbol))
+        s4o.print(GET_EXTERNAL_FB_BY_REF);
+      else
+        s4o.print(GET_EXTERNAL_BY_REF);
+    }
     else if (vartype == search_var_instance_decl_c::located_vt)
       s4o.print(GET_LOCATED_BY_REF);
     else
       s4o.print(GET_VAR_BY_REF);
   }
   else {
-    if (vartype == search_var_instance_decl_c::external_vt)
-      s4o.print(GET_EXTERNAL);
+    if (vartype == search_var_instance_decl_c::external_vt) {
+      if (search_var_instance_decl->type_is_fb(symbol))
+        s4o.print(GET_EXTERNAL_FB);
+      else
+        s4o.print(GET_EXTERNAL);
+    }
     else if (vartype == search_var_instance_decl_c::located_vt)
       s4o.print(GET_LOCATED);
     else
@@ -160,24 +168,33 @@
 }
 
 void *print_setter(symbol_c* symbol,
-		symbol_c* type,
-		symbol_c* value,
-		symbol_c* fb_symbol = NULL,
-		symbol_c* fb_value = NULL) {
+        symbol_c* type,
+        symbol_c* value,
+        symbol_c* fb_symbol = NULL,
+        symbol_c* fb_value = NULL) {
   
   bool type_is_complex = false;
   if (fb_symbol == NULL) {
     unsigned int vartype = search_var_instance_decl->get_vartype(symbol);
     type_is_complex = search_var_instance_decl->type_is_complex(symbol);
-    if (vartype == search_var_instance_decl_c::external_vt)
-      s4o.print(SET_EXTERNAL);
+    if (vartype == search_var_instance_decl_c::external_vt) {
+      if (search_var_instance_decl->type_is_fb(symbol))
+        s4o.print(SET_EXTERNAL_FB);
+      else
+        s4o.print(SET_EXTERNAL);
+    }
     else if (vartype == search_var_instance_decl_c::located_vt)
       s4o.print(SET_LOCATED);
     else
       s4o.print(SET_VAR);
   }
-  else
-	s4o.print(SET_VAR);
+  else {
+    unsigned int vartype = search_var_instance_decl->get_vartype(fb_symbol);
+    if (vartype == search_var_instance_decl_c::external_vt)
+      s4o.print(SET_EXTERNAL_FB);
+    else
+      s4o.print(SET_VAR);
+  }
   s4o.print("(");
 
   if (fb_symbol != NULL) {
@@ -274,14 +291,14 @@
   if (strlen(symbol->value) == 0) ERROR;
   if (this->is_variable_prefix_null()) {
     if (wanted_variablegeneration != fparam_output_vg)
-	  s4o.print("*(");
+      s4o.print("*(");
   }
   else {
     switch (wanted_variablegeneration) {
       case expression_vg:
-  	    s4o.print(GET_LOCATED);
-  	    s4o.print("(");
-  	    break;
+        s4o.print(GET_LOCATED);
+        s4o.print("(");
+        break;
       case fparam_output_vg:
         s4o.print(GET_LOCATED_BY_REF);
         s4o.print("(");
@@ -293,7 +310,7 @@
   this->print_variable_prefix();
   s4o.printlocation(symbol->value + 1);
   if ((this->is_variable_prefix_null() && wanted_variablegeneration != fparam_output_vg) ||
-	  wanted_variablegeneration != assignment_vg)
+      wanted_variablegeneration != assignment_vg)
     s4o.print(")");
   return NULL;
 }
@@ -311,8 +328,8 @@
     case complextype_base_assignment_vg:
       symbol->record_variable->accept(*this);
       if (!type_is_complex) {
-    	s4o.print(".");
-    	symbol->field_selector->accept(*this);
+        s4o.print(".");
+        symbol->field_selector->accept(*this);
       }
       break;
     case complextype_suffix_vg:
@@ -329,12 +346,12 @@
       break;
     default:
       if (this->is_variable_prefix_null()) {
-    	symbol->record_variable->accept(*this);
-    	s4o.print(".");
-    	symbol->field_selector->accept(*this);
+        symbol->record_variable->accept(*this);
+        s4o.print(".");
+        symbol->field_selector->accept(*this);
       }
       else
-    	print_getter(symbol);
+        print_getter(symbol);
       break;
   }
   return NULL;
@@ -363,18 +380,18 @@
       break;
     default:
       if (this->is_variable_prefix_null()) {
-    	symbol->subscripted_variable->accept(*this);
-
-    	current_array_type = search_varfb_instance_type->get_basetype_decl(symbol->subscripted_variable);
-    	if (current_array_type == NULL) ERROR;
-
-    	s4o.print(".table");
+        symbol->subscripted_variable->accept(*this);
+
+        current_array_type = search_varfb_instance_type->get_basetype_decl(symbol->subscripted_variable);
+        if (current_array_type == NULL) ERROR;
+
+        s4o.print(".table");
         symbol->subscript_list->accept(*this);
 
         current_array_type = NULL;
       }
       else
-    	print_getter(symbol);
+        print_getter(symbol);
       break;
   }
   return NULL;
@@ -385,9 +402,9 @@
   array_dimension_iterator_c* array_dimension_iterator = new array_dimension_iterator_c(current_array_type);
   for (int i =  0; i < symbol->n; i++) {
     symbol_c* dimension = array_dimension_iterator->next();
-	if (dimension == NULL) ERROR;
-
-	s4o.print("[(");
+    if (dimension == NULL) ERROR;
+
+    s4o.print("[(");
     symbol->elements[i]->accept(*this);
     s4o.print(") - (");
     dimension->accept(*this);
@@ -819,7 +836,7 @@
     print_check_function(left_type, symbol->r_exp);
   }
   else {
-	print_setter(symbol->l_exp, left_type, symbol->r_exp);
+    print_setter(symbol->l_exp, left_type, symbol->r_exp);
   }
   return NULL;
 }
@@ -894,7 +911,9 @@
   /* now call the function... */
   function_block_type_name->accept(*this);
   s4o.print(FB_FUNCTION_SUFFIX);
-  s4o.print("(&");
+  s4o.print("(");
+  if (search_var_instance_decl->get_vartype(symbol->fb_name) != search_var_instance_decl_c::external_vt)
+    s4o.print("&");
   print_variable_prefix();
   symbol->fb_name->accept(*this);
   s4o.print(")");
@@ -1085,7 +1104,7 @@
       case_element_iterator = new case_element_iterator_c(symbol->case_list, case_element_iterator_c::element_single);
       for (element = case_element_iterator->next(); element != NULL; element = case_element_iterator->next()) {
         if (first_element) first_element = false;
-    	s4o.print(s4o.indent_spaces + "case ");
+        s4o.print(s4o.indent_spaces + "case ");
         element->accept(*this);
         s4o.print(":\n");
       }
@@ -1101,7 +1120,7 @@
             first_subrange_case_list = false;
           }
           else {
-        	  s4o.print(s4o.indent_spaces + "else if (");
+            s4o.print(s4o.indent_spaces + "else if (");
           }
           first_element = false;
         }
@@ -1129,9 +1148,9 @@
         s4o.indent_left();
         break;
       case subrange_cg:
-    	s4o.indent_left();
-  	    s4o.print(s4o.indent_spaces + "}\n");
-  	    break;
+        s4o.indent_left();
+        s4o.print(s4o.indent_spaces + "}\n");
+        break;
       default:
         break;
     }
--- a/stage4/generate_c/generate_c_typedecl.cc	Thu Jan 03 17:04:04 2013 +0000
+++ b/stage4/generate_c/generate_c_typedecl.cc	Thu Jan 03 18:23:07 2013 +0000
@@ -98,6 +98,9 @@
       return NULL;
     }
 
+    bool type_is_fb(symbol_c* type_decl) {
+      return search_base_type_c::type_is_fb(type_decl);
+    }
 
 /***************************/
 /* B 0 - Programming Model */
@@ -345,19 +348,19 @@
   current_basetypedeclaration = none_bd;
 
   if (array_is_derived)
-	s4o_incl.print("__DECLARE_DERIVED_TYPE(");
+    s4o_incl.print("__DECLARE_DERIVED_TYPE(");
   else
-	s4o_incl.print("__DECLARE_ARRAY_TYPE(");
+    s4o_incl.print("__DECLARE_ARRAY_TYPE(");
   current_type_name->accept(*basedecl);
   s4o_incl.print(",");
   current_basetypedeclaration = arraybasetypeincl_bd;
   symbol->array_spec_init->accept(*this);
   current_basetypedeclaration = none_bd;
   if (!array_is_derived) {
-	s4o_incl.print(",");
-	current_basetypedeclaration = arraysubrange_bd;
-	symbol->array_spec_init->accept(*this);
-	current_basetypedeclaration = none_bd;
+    s4o_incl.print(",");
+    current_basetypedeclaration = arraysubrange_bd;
+    symbol->array_spec_init->accept(*this);
+    current_basetypedeclaration = none_bd;
   }
   s4o_incl.print(")\n");
 
@@ -374,19 +377,19 @@
   
   if (current_typedefinition == array_td) {
     switch (current_basetypedeclaration) {
-	  case arrayderiveddeclaration_bd:
-	    array_is_derived = dynamic_cast<identifier_c *>(symbol->array_specification) != NULL;
-	    break;
-	  default:
-	    if (array_is_derived)
-		  symbol->array_specification->accept(*basedecl);
-	    else
-		  symbol->array_specification->accept(*this);
-	    break;
+      case arrayderiveddeclaration_bd:
+        array_is_derived = dynamic_cast<identifier_c *>(symbol->array_specification) != NULL;
+        break;
+      default:
+        if (array_is_derived)
+          symbol->array_specification->accept(*basedecl);
+        else
+          symbol->array_specification->accept(*this);
+        break;
     }
   }
   else {
-	symbol->array_specification->accept(*basedecl);
+    symbol->array_specification->accept(*basedecl);
   }
   return NULL;
 }
@@ -441,11 +444,11 @@
   s4o_incl.print(")\n");
 
   if (search_base_type_c::type_is_subrange(symbol->simple_type_name)) {
-	s4o.print("#define __CHECK_");
-	current_type_name->accept(*this);
-	s4o.print(" __CHECK_");
-	symbol->simple_spec_init->accept(*this);
-	s4o.print("\n");
+    s4o.print("#define __CHECK_");
+    current_type_name->accept(*this);
+    s4o.print(" __CHECK_");
+    symbol->simple_spec_init->accept(*this);
+    s4o.print("\n");
   }
 
   return NULL;
--- a/stage4/generate_c/generate_c_vardecl.cc	Thu Jan 03 17:04:04 2013 +0000
+++ b/stage4/generate_c/generate_c_vardecl.cc	Thu Jan 03 18:23:07 2013 +0000
@@ -26,31 +26,31 @@
 
 class initialization_analyzer_c: public null_visitor_c {
   public:
-	typedef enum {
-	  simple_it,
-	  array_it,
-	  struct_it
-	} initialization_type_t;
+    typedef enum {
+      simple_it,
+      array_it,
+      struct_it
+    } initialization_type_t;
 
   private:
 
-	initialization_type_t current_type;
+    initialization_type_t current_type;
 
   public:
-	initialization_analyzer_c(symbol_c* symbol) {
-	  current_type = simple_it;
+    initialization_analyzer_c(symbol_c* symbol) {
+      current_type = simple_it;
       symbol->accept(*this);
-	}
-	~initialization_analyzer_c(void) {}
-
-	initialization_type_t get_initialization_type(void) {
-	  return current_type;
-	}
-
-	void *visit(array_initial_elements_list_c *symbol) {
+    }
+    ~initialization_analyzer_c(void) {}
+
+    initialization_type_t get_initialization_type(void) {
+      return current_type;
+    }
+
+    void *visit(array_initial_elements_list_c *symbol) {
       current_type = array_it;
       return NULL;
-	}
+    }
 
     void *visit(structure_element_initialization_list_c *symbol) {
       current_type = struct_it;
@@ -94,6 +94,10 @@
       array_specification->accept(*this);
     }
 
+    void set_array_default_initialisation(symbol_c *array_initialization) {
+      array_default_initialization = array_initialization;
+    }
+
     void init_array(symbol_c *var1_list, symbol_c *array_specification, symbol_c *array_initialization) {
       int i;
       
@@ -250,7 +254,7 @@
               array_initial_elements_c *array_initial_element = dynamic_cast<array_initial_elements_c *>(symbol->elements[i]);
             
               if (array_initial_element != NULL) {
-            	  symbol->elements[i]->accept(*this);
+                symbol->elements[i]->accept(*this);
               }
             }
             current_initialization_count++;
@@ -269,7 +273,7 @@
  
       /* This code assumes that unsigned long long int is >= uint64_t */
       if (std::numeric_limits< uint64_t >::max() > std::numeric_limits< unsigned long long int >::max()) 
-	ERROR_MSG("Assertion (sizeof(uint64_t) > sizeof(unsigned long long int)) failed! Compiler cannot execute correctly on the current platform!");
+        ERROR_MSG("Assertion (sizeof(uint64_t) > sizeof(unsigned long long int)) failed! Compiler cannot execute correctly on the current platform!");
       
       switch (current_mode) {
         case initializationvalue_am:
@@ -421,6 +425,7 @@
       if (next_element == element_count) {
         current_element_default_value = spec_init_sperator_c::get_init(symbol->spec_init);
         current_element_type = spec_init_sperator_c::get_spec(symbol->spec_init);
+        if (current_element_type == NULL) ERROR;
         return symbol->structure_element_name;
       }
       /* not yet the desired element... */
@@ -500,6 +505,7 @@
   private:
     symbol_c* structure_type_decl;
     symbol_c* current_element_type;
+    symbol_c* current_element_default_value;
 
   public:
     generate_c_structure_initialization_c(stage4out_c *s4o_ptr): generate_c_typedecl_c(s4o_ptr) {}
@@ -508,6 +514,7 @@
     void init_structure_default(symbol_c *structure_type_name) {
       structure_type_decl = NULL;
       current_element_type = NULL;
+      current_element_default_value = NULL;
       
       current_mode = initdefault_sm;
       structure_type_name->accept(*this);
@@ -604,19 +611,21 @@
         if (i > 1)
           s4o.print(",");
         
+        current_element_type = structure_iterator.element_type();
+        if (current_element_type == NULL) ERROR;
+
+        /* Check whether default value specified in structure declaration...*/
+        current_element_default_value = structure_iterator.default_value();
+
         /* Get the value from an initialization */
         symbol_c *element_value = structure_init_element_iterator.search(element_name);
         
         if (element_value == NULL) {
           /* No value given for parameter, so we must use the default... */
-          /* First check whether default value specified in function declaration...*/
-          element_value = structure_iterator.default_value();
-          current_element_type = structure_iterator.element_type();
+          element_value = current_element_default_value;
         }
         
         if (element_value == NULL) {
-          if (current_element_type == NULL) ERROR;
-          
           /* If not, get the default value of this variable's type */
           element_value = type_initial_value_c::get(current_element_type);
         }
@@ -644,6 +653,8 @@
     void *visit(array_initial_elements_list_c *symbol) {
       generate_c_array_initialization_c *array_initialization = new generate_c_array_initialization_c(&s4o);
       array_initialization->init_array_size(current_element_type);
+      if (current_element_default_value != NULL)
+        array_initialization->set_array_default_initialisation(current_element_default_value);
       array_initialization->init_array_values(symbol);
       delete array_initialization;
       return NULL;
@@ -900,17 +911,17 @@
     symbol_c *globalnamespace;
 
     void *print_retain(void) {
-	  s4o.print(",");
+      s4o.print(",");
       switch (current_varqualifier) {
-		case retain_vq:
+        case retain_vq:
           s4o.print("1");
           break;
         case non_retain_vq:
           s4o.print("0");
           break;
-		default:
-		  s4o.print("retain");
-		  break;
+        default:
+          s4o.print("retain");
+          break;
       }
       return NULL;
     }
@@ -932,32 +943,32 @@
         for(int i = 0; i < list->n; i++) {
           s4o.print(s4o.indent_spaces);
           if (wanted_varformat == local_vf) {
-        	if (!is_fb) {
-        	  s4o.print(DECLARE_VAR);
-        	  s4o.print("(");
-        	}
-        	this->current_var_type_symbol->accept(*this);
-        	if (is_fb)
-        	  s4o.print(" ");
-        	else
-        	  s4o.print(",");
-        	print_variable_prefix();
+            if (!is_fb) {
+              s4o.print(DECLARE_VAR);
+              s4o.print("(");
+            }
+            this->current_var_type_symbol->accept(*this);
+            if (is_fb)
+              s4o.print(" ");
+            else
+              s4o.print(",");
+            print_variable_prefix();
           }
           else if (wanted_varformat == localinit_vf) {
-        	this->current_var_type_symbol->accept(*this);
+            this->current_var_type_symbol->accept(*this);
             s4o.print(" ");
             print_variable_prefix();
           }
           else if (wanted_varformat == init_vf) {
-        	s4o.print(SET_VAR);
-        	s4o.print("(");
-        	print_variable_prefix();
-        	s4o.print(",");
+            s4o.print(SET_VAR);
+            s4o.print("(");
+            print_variable_prefix();
+            s4o.print(",");
           }
           list->elements[i]->accept(*this);
           if (wanted_varformat != local_vf) {
-        	if (wanted_varformat == localinit_vf &&
-        		(current_vartype & inoutput_vt) != 0) {
+            if (wanted_varformat == localinit_vf &&
+                (current_vartype & inoutput_vt) != 0) {
               s4o.print(";\n");
               s4o.print(s4o.indent_spaces);
               s4o.print("if (__");
@@ -988,13 +999,13 @@
               s4o.print(s4o.indent_spaces);
               s4o.print("}\n");
             }
-        	else if (wanted_varformat == init_vf) {
-        	  s4o.print(",");
-        	  this->current_var_init_symbol->accept(*this);
-        	  s4o.print(");\n");
-        	}
-        	else {
-        	  if (this->current_var_init_symbol != NULL) {
+            else if (wanted_varformat == init_vf) {
+              s4o.print(",");
+              this->current_var_init_symbol->accept(*this);
+              s4o.print(");\n");
+            }
+            else {
+              if (this->current_var_init_symbol != NULL) {
                 s4o.print(" = ");
                 this->current_var_init_symbol->accept(*this);
               }
@@ -1002,7 +1013,7 @@
             }
           }
           else if (is_fb)
-        	s4o.print(";\n");
+            s4o.print(";\n");
           else
             s4o.print(")\n");
         }
@@ -1266,9 +1277,9 @@
         (wanted_varformat == localinit_vf)) {
       s4o.print(s4o.indent_spaces);
       if (wanted_varformat == local_vf) {
-    	s4o.print(DECLARE_VAR);
-    	s4o.print("(");
-    	symbol->type->accept(*this);
+        s4o.print(DECLARE_VAR);
+        s4o.print("(");
+        symbol->type->accept(*this);
         s4o.print(",");
       }
       else if (wanted_varformat == localinit_vf) {
@@ -1278,7 +1289,7 @@
       print_variable_prefix();
       symbol->name->accept(*this);
       if (wanted_varformat == local_vf)
-    	s4o.print(")\n");
+        s4o.print(")\n");
       else {
         s4o.print(" = ");
         symbol->value->accept(*this);
@@ -1324,8 +1335,8 @@
         (wanted_varformat == localinit_vf)) {
       s4o.print(s4o.indent_spaces);
       if (wanted_varformat == local_vf) {
-    	s4o.print(DECLARE_VAR);
-    	s4o.print("(");
+        s4o.print(DECLARE_VAR);
+        s4o.print("(");
         symbol->type->accept(*this);
         s4o.print(",");
       }
@@ -1336,9 +1347,9 @@
       print_variable_prefix();
       symbol->name->accept(*this);
       if (wanted_varformat == local_vf)
-    	s4o.print(")\n");
+        s4o.print(")\n");
       else
-    	s4o.print(" = __BOOL_LITERAL(TRUE);\n");
+        s4o.print(" = __BOOL_LITERAL(TRUE);\n");
     }
 
     if (wanted_varformat == foutputassign_vf) {
@@ -1569,10 +1580,10 @@
 
 void *visit(array_initial_elements_list_c *symbol) {
   if (wanted_varformat == localinit_vf || wanted_varformat == constructorinit_vf) {
-	generate_c_array_initialization_c *array_initialization = new generate_c_array_initialization_c(&s4o);
-	array_initialization->init_array_size(this->current_var_type_symbol);
-	array_initialization->init_array_values(this->current_var_init_symbol);
-	delete array_initialization;
+    generate_c_array_initialization_c *array_initialization = new generate_c_array_initialization_c(&s4o);
+    array_initialization->init_array_size(this->current_var_type_symbol);
+    array_initialization->init_array_values(this->current_var_init_symbol);
+    delete array_initialization;
   }
   return NULL;
 }
@@ -1614,7 +1625,7 @@
     generate_c_structure_initialization_c *structure_initialization = new generate_c_structure_initialization_c(&s4o);
     structure_initialization->init_structure_default(this->current_var_type_symbol);
     structure_initialization->init_structure_values(this->current_var_init_symbol);
-	delete structure_initialization;
+    delete structure_initialization;
   }
   return NULL;
 }
@@ -1729,15 +1740,15 @@
       print_retain();
       s4o.print(")\n");
       if (this->current_var_init_symbol != NULL) {
-    	s4o.print(s4o.indent_spaces);
-    	s4o.print(INIT_LOCATED_VALUE);
-    	s4o.print("(");
-    	print_variable_prefix();
-    	if (symbol->variable_name != NULL)
+        s4o.print(s4o.indent_spaces);
+        s4o.print(INIT_LOCATED_VALUE);
+        s4o.print("(");
+        print_variable_prefix();
+        if (symbol->variable_name != NULL)
           symbol->variable_name->accept(*this);
         else
           symbol->location->accept(*this);
-    	s4o.print(",");
+        s4o.print(",");
         this->current_var_init_symbol->accept(*this);
         s4o.print(")");
       }
@@ -1837,13 +1848,17 @@
    */
   this->current_var_type_symbol = symbol->specification;
   this->current_var_init_symbol = NULL;
+  bool is_fb = type_is_fb(this->current_var_type_symbol);
 
   /* now to produce the c equivalent... */
   switch (wanted_varformat) {
     case local_vf:
     case localinit_vf:
       s4o.print(s4o.indent_spaces);
-      s4o.print(DECLARE_EXTERNAL);
+      if (is_fb)
+        s4o.print(DECLARE_EXTERNAL_FB);
+      else
+        s4o.print(DECLARE_EXTERNAL);
       s4o.print("(");
       this->current_var_type_symbol->accept(*this);
       s4o.print(",");
@@ -1853,7 +1868,10 @@
 
     case constructorinit_vf:
       s4o.print(nv->get());
-      s4o.print(INIT_EXTERNAL);
+      if (is_fb)
+        s4o.print(INIT_EXTERNAL_FB);
+      else
+        s4o.print(INIT_EXTERNAL);
       s4o.print("(");
       this->current_var_type_symbol->accept(*this);
       s4o.print(",");
@@ -1982,50 +2000,50 @@
 
     case constructorinit_vf:
       if (symbol->global_var_name != NULL) {
-    	s4o.print(nv->get());
-    	s4o.print(INIT_GLOBAL_LOCATED);
-    	s4o.print("(");
-    	if (this->resource_name != NULL) {
-    	  this->resource_name->accept(*this);
-    	}
+        s4o.print(nv->get());
+        s4o.print(INIT_GLOBAL_LOCATED);
+        s4o.print("(");
+        if (this->resource_name != NULL) {
+          this->resource_name->accept(*this);
+        }
         s4o.print(",");
         symbol->global_var_name->accept(*this);
-      	s4o.print(",");
-      	symbol->location->accept(*this);
+        s4o.print(",");
+        symbol->location->accept(*this);
         print_retain();
-      	s4o.print(")");
+        s4o.print(")");
       }
       if (this->current_var_init_symbol != NULL) {
-	    s4o.print(nv->get());
-	    s4o.print(INIT_GLOBAL);
-	    s4o.print("(");
-	    this->current_var_type_symbol->accept(*this);
-	    s4o.print(",");
-	    if (symbol->global_var_name != NULL)
-		  symbol->global_var_name->accept(*this);
-	    else
-		  symbol->location->accept(*this);
-	    s4o.print(",");
-	    s4o.print(INITIAL_VALUE);
-	    s4o.print("(");
-	    this->current_var_init_symbol->accept(*this);
-	    s4o.print(")");
-	    print_retain();
-	    s4o.print(")");
+        s4o.print(nv->get());
+        s4o.print(INIT_GLOBAL);
+        s4o.print("(");
+        this->current_var_type_symbol->accept(*this);
+        s4o.print(",");
+        if (symbol->global_var_name != NULL)
+          symbol->global_var_name->accept(*this);
+        else
+	      symbol->location->accept(*this);
+        s4o.print(",");
+        s4o.print(INITIAL_VALUE);
+        s4o.print("(");
+        this->current_var_init_symbol->accept(*this);
+        s4o.print(")");
+        print_retain();
+        s4o.print(")");
       }
       break;
     
     case globalprototype_vf:
       s4o.print(s4o.indent_spaces);
       s4o.print(DECLARE_GLOBAL_PROTOTYPE);
-	  s4o.print("(");
-	  this->current_var_type_symbol->accept(*this);
-	  s4o.print(",");
-	  if (symbol->global_var_name != NULL)
-		symbol->global_var_name->accept(*this);
-	  else
-		symbol->location->accept(*this);
-	  s4o.print(")\n");
+      s4o.print("(");
+      this->current_var_type_symbol->accept(*this);
+      s4o.print(",");
+      if (symbol->global_var_name != NULL)
+        symbol->global_var_name->accept(*this);
+      else
+        symbol->location->accept(*this);
+      s4o.print(")\n");
       break;
     
     default:
@@ -2050,6 +2068,7 @@
 void *visit(global_var_list_c *symbol) {
   TRACE("global_var_list_c");
   list_c *list = dynamic_cast<list_c *>(symbol);
+  bool is_fb = type_is_fb(this->current_var_type_symbol);
   /* should NEVER EVER occur!! */
   if (list == NULL) ERROR;
 
@@ -2058,9 +2077,12 @@
     case local_vf:
     case localinit_vf:
       for(int i = 0; i < list->n; i++) {
-    	s4o.print(s4o.indent_spaces);
-    	s4o.print(DECLARE_GLOBAL);
-    	s4o.print("(");
+        s4o.print(s4o.indent_spaces);
+        if (is_fb)
+          s4o.print(DECLARE_GLOBAL_FB);
+        else
+          s4o.print(DECLARE_GLOBAL);
+        s4o.print("(");
         this->current_var_type_symbol->accept(*this);
         s4o.print(",");
         if(this->resource_name != NULL)
@@ -2072,27 +2094,32 @@
       break;
 
     case constructorinit_vf:
-      if (this->current_var_init_symbol != NULL) {
+      if (this->current_var_init_symbol != NULL || is_fb) {
         for(int i = 0; i < list->n; i++) {
           s4o.print(nv->get());
 
-          s4o.print(INIT_GLOBAL);
+          if (is_fb)
+            s4o.print(INIT_GLOBAL_FB);
+          else
+            s4o.print(INIT_GLOBAL);
           s4o.print("(");
           this->current_var_type_symbol->accept(*this);
           s4o.print(",");
           list->elements[i]->accept(*this);
-          s4o.print(",");
-          s4o.print(INITIAL_VALUE);
-          s4o.print("(");
-          this->current_var_init_symbol->accept(*this);
-          s4o.print(")");
+          if (this->current_var_init_symbol != NULL) {
+            s4o.print(",");
+            s4o.print(INITIAL_VALUE);
+            s4o.print("(");
+            this->current_var_init_symbol->accept(*this);
+            s4o.print(")");
+          }
           print_retain();
           s4o.print(")");
 #if 0
- 	  /* The following code would be for globalinit_vf !!
-	   * But it is not currently required...
-	   */
-	  s4o.print(s4o.indent_spaces + "__ext_element_c<");
+      /* The following code would be for globalinit_vf !!
+       * But it is not currently required...
+       */
+      s4o.print(s4o.indent_spaces + "__ext_element_c<");
           this->current_var_type_symbol->accept(*this);
           s4o.print("> ");
           if (this->globalnamespace != NULL) {
@@ -2108,7 +2135,7 @@
             s4o.print(">(");
             this->current_var_init_symbol->accept(*this);
             s4o.print(")");
-	  }
+      }
           s4o.print(";\n");
 #endif
         }
@@ -2515,19 +2542,19 @@
       case function_param_iterator_c::direction_extref:
 #if 0
         if (param_value == NULL)
-	  /* This is illegal in ST and IL languages.
-	   * All variables declared in a VAR_EXTERNAL __must__
-	   * be initialised to reference a specific VAR_GLOBAL variable!!
-	   *
-	   * The semantic checker should have caught this, we check again just the
-	   * same (especially since the semantic checker has not yet been written!).
-	   */
-	  ERROR;
+      /* This is illegal in ST and IL languages.
+       * All variables declared in a VAR_EXTERNAL __must__
+       * be initialised to reference a specific VAR_GLOBAL variable!!
+       *
+       * The semantic checker should have caught this, we check again just the
+       * same (especially since the semantic checker has not yet been written!).
+       */
+      ERROR;
         s4o.print(nv->get());
         s4o.print("&");
         param_value->accept(*this);
 #endif
-	break;
+    break;
     } /* switch */
   } /* for(...) */
 
--- a/stage4/generate_c/generate_var_list.cc	Thu Jan 03 17:04:04 2013 +0000
+++ b/stage4/generate_c/generate_var_list.cc	Thu Jan 03 18:23:07 2013 +0000
@@ -131,14 +131,14 @@
       var_type_symbol->accept(*this);
 
       if (this->current_var_type_symbol == NULL)
-    	this->current_var_type_symbol = var_type_symbol;
+        this->current_var_type_symbol = var_type_symbol;
 
       return (this->current_var_type_symbol);
     }
 
     symbol_c *get_current_type_name(void) {
       if (this->current_var_type_name == NULL)
-    	return (this->current_var_type_symbol);
+        return (this->current_var_type_symbol);
 
       return (this->current_var_type_name);
     }
@@ -187,8 +187,7 @@
 class generate_var_list_c: protected generate_c_typedecl_c {
   
   public:
-    typedef struct
-    {
+    typedef struct {
       symbol_c *symbol;
     } SYMBOL;
 
@@ -328,15 +327,17 @@
         case search_type_symbol_c::function_block_vtc:
           this->current_var_type_name->accept(*this);
           s4o.print(";\n");
-          SYMBOL *current_name;
-          symbol_c *tmp_var_type;
-          current_name = new SYMBOL;
-          current_name->symbol = symbol;
-          tmp_var_type = this->current_var_type_symbol;
-          current_symbol_list.push_back(*current_name);
-          this->current_var_type_symbol->accept(*this);
-          current_symbol_list.pop_back();
-          this->current_var_type_symbol = tmp_var_type;
+          if (this->current_var_class_category != external_vcc) {
+              SYMBOL *current_name;
+              symbol_c *tmp_var_type;
+              current_name = new SYMBOL;
+              current_name->symbol = symbol;
+              tmp_var_type = this->current_var_type_symbol;
+              current_symbol_list.push_back(*current_name);
+              this->current_var_type_symbol->accept(*this);
+              current_symbol_list.pop_back();
+              this->current_var_type_symbol = tmp_var_type;
+          }
           break;
         case search_type_symbol_c::array_vtc:
           this->current_var_type_name->accept(*this);
@@ -374,7 +375,7 @@
       s4o.print(str);
     }
     
-    void print_symbol_list(void) {
+    void print_symbol_list() {
       std::list<SYMBOL>::iterator pt;
       for(pt = current_symbol_list.begin(); pt != current_symbol_list.end(); pt++) {
         pt->symbol->accept(*this);
@@ -679,20 +680,20 @@
     // SYM_REF2(global_var_spec_c, global_var_name, location)
     void *visit(global_var_spec_c *symbol) {
       search_location_type_c search_location_type;
-	  switch (search_location_type.get_location_type(symbol->location)) {
-		case search_location_type_c::input_lt:
-		  this->current_var_class_category = located_input_vcc;
-		  break;
-		case search_location_type_c::memory_lt:
-		  this->current_var_class_category = located_memory_vcc;
-		  break;
-		case search_location_type_c::output_lt:
-		  this->current_var_class_category = located_output_vcc;
-		  break;
-		default:
-		  ERROR;
-	      break;
-	  }
+      switch (search_location_type.get_location_type(symbol->location)) {
+        case search_location_type_c::input_lt:
+          this->current_var_class_category = located_input_vcc;
+          break;
+        case search_location_type_c::memory_lt:
+          this->current_var_class_category = located_memory_vcc;
+          break;
+        case search_location_type_c::output_lt:
+          this->current_var_class_category = located_output_vcc;
+          break;
+        default:
+          ERROR;
+          break;
+      }
 
       if (symbol->global_var_name != NULL)
         declare_variable(symbol->global_var_name);