ncurses 5.3
[ncurses.git] / Ada95 / gen / gen.c
index 3a1426f4705d81879ec19dc076305db3989c1d44..11ba3d73706a4417fcf966bf57183896043bfc3a 100644 (file)
@@ -1,28 +1,39 @@
-/*----------------------------------------------------------------------------
-//                                                                          --
-//                           GNAT ncurses Binding                           --
-//                                                                          --
-//                                  gen.c                                   --
-//                                                                          --
-//                                 B O D Y                                  --
-//                                                                          --
-//  Version 00.92                                                           --
-//                                                                          --
-//  The ncurses Ada95 binding is copyrighted 1996 by                        --
-//  Juergen Pfeifer, Email: Juergen.Pfeifer@T-Online.de                     --
-//                                                                          --
-//  Permission is hereby granted to reproduce and distribute this           --
-//  binding by any means and for any fee, whether alone or as part          --
-//  of a larger distribution, in source or in binary form, PROVIDED         --
-//  this notice is included with any such distribution, and is not          --
-//  removed from any of its header files. Mention of ncurses and the        --
-//  author of this binding in any applications linked with it is            --
-//  highly appreciated.                                                     --
-//                                                                          --
-//  This binding comes AS IS with no warranty, implied or expressed.        --
-//----------------------------------------------------------------------------
+/****************************************************************************
+ * Copyright (c) 1998,2000 Free Software Foundation, Inc.                   *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+
+/****************************************************************************
+ *   Author:  Juergen Pfeifer, 1996                                         *
+ *   Contact: http://www.familiepfeifer.de/Contact.aspx?Lang=en             *
+ ****************************************************************************/
+
+/*
     Version Control
-    $Revision: 1.8 $
+    $Revision: 1.35 $
   --------------------------------------------------------------------------*/
 /*
   This program generates various record structures and constants from the
   to produce the real source.
   */
 
+#include <stdlib.h>
+#include <stddef.h>
 #include <string.h>
 #include <assert.h>
 #include <ctype.h>
-#include <time.h>
 
 #include <menu.h>
 #include <form.h>
 
 #define RES_NAME "Reserved"
 
+static const char *model = "";
 static int little_endian = 0;
 
 typedef struct {
   const char *name;
-  unsigned int attr;
+  unsigned long attr;
 } name_attribute_pair;
 
 static int find_pos (char *s, unsigned len, int *low, int *high)
 {
-  unsigned int i,j; 
+  unsigned int i,j;
   int l = 0;
 
   *high = -1;
@@ -83,29 +96,25 @@ static int find_pos (char *s, unsigned len, int *low, int *high)
   return (*high >= 0 && (*low <= *high)) ? *low : -1;
 }
 
-static void gen_reps ( const name_attribute_pair *nap,
-                      const char *name,
-                      int len)
+/*
+ * This helper routine generates a representation clause for a
+ * record type defined in the binding.
+ * We are only dealing with record types which are of 32 or 16
+ * bit size, i.e. they fit into an (u)int or a (u)short.
+ */
+static void
+gen_reps
+(const name_attribute_pair *nap, /* array of name_attribute_pair records */
+ const char *name,               /* name of the represented record type  */
+ int len,                        /* size of the record in bytes          */
+ int bias)
 {
-  int i,l,cnt = 0,low,high;
-  int width = strlen(RES_NAME);
-  int bias = 0;
-  unsigned int a;
-  unsigned int mask = 0;
-  char *suffix;
+  int i,n,l,cnt = 0,low,high;
+  int width = strlen(RES_NAME) + 3;
+  unsigned long a;
+  unsigned long mask = 0;
 
-  assert (nap);
-
-  if (len == sizeof(int)/2)
-    {
-      bias = little_endian ? 8 * len : 0;
-      suffix = " / 2";
-    }
-  else
-    {
-      assert(len==sizeof(int));
-      suffix = "";
-    }
+  assert (nap!=NULL);
 
   for (i=0; nap[i].name != (char *)0; i++)
     {
@@ -121,10 +130,6 @@ static void gen_reps ( const name_attribute_pair *nap,
   for (i=0; nap[i].name != (char *)0; i++)
     {
       printf("         %-*s : Boolean;\n",width,nap[i].name);
-    }  
-  if (cnt != 8*len)
-    {
-      printf("         %-*s : Boolean;\n",width,RES_NAME);
     }
   printf("      end record;\n");
   printf("   pragma Pack (%s);\n",name);
@@ -139,33 +144,25 @@ static void gen_reps ( const name_attribute_pair *nap,
       mask |= a;
       l = find_pos( (char *)&a,sizeof(a),&low,&high );
       if (l>=0)
-       printf("         %-*s at 0 range %2d .. %2d;\n",width,nap[i].name,low-bias,high-bias);
-    }  
-  if (cnt != 8*len)
-    {
-      mask = ~mask;
-      assert(mask);
-      if (little_endian)
-       l = 8*len - 1;
-      else
-       l = 0;
-      printf("         %-*s at 0 range %2d .. %2d;\n",width,RES_NAME,l,l);
+       printf("         %-*s at 0 range %2d .. %2d;\n",width,nap[i].name,
+              low-bias,high-bias);
     }
+  i = 1; n = cnt;
   printf("      end record;\n");
-  printf("   for %s'Size use Interfaces.C.int'Size%s;\n", name, suffix);
+  printf("   for %s'Size use %d;\n", name, 8*len);
   printf("   --  Please note: this rep. clause is generated and may be\n");
   printf("   --               different on your system.");
 }
 
 
-static void chtype_rep (const char *name, int mask)
+static void chtype_rep (const char *name, attr_t mask)
 {
-  int x = -1;
-  int t = x & mask;
+  attr_t x = -1;
+  attr_t t = x & mask;
   int low, high;
   int l = find_pos ((char *)&t, sizeof(t), &low, &high);
   if (l>=0)
-    printf("         %-5s at 0 range %2d .. %2d;\n",name,low,high); 
+    printf("         %-5s at 0 range %2d .. %2d;\n",name,low,high);
 }
 
 static void gen_chtype_rep(const char *name)
@@ -174,7 +171,7 @@ static void gen_chtype_rep(const char *name)
   chtype_rep("Ch",A_CHARTEXT);
   chtype_rep("Color",A_COLOR);
   chtype_rep("Attr",(A_ATTRIBUTES&~A_COLOR));
-  printf("      end record;\n   for %s'Size use Interfaces.C.int'Size;\n",name);
+  printf("      end record;\n   for %s'Size use %ld;\n", name, (long)(8*sizeof(chtype)));
   printf("      --  Please note: this rep. clause is generated and may be\n");
   printf("      --               different on your system.\n");
 }
@@ -185,7 +182,7 @@ static void mrep_rep (const char *name, void *rec)
   int low, high;
   int l = find_pos((char *)rec, sizeof(MEVENT), &low, &high);
   if (l>=0)
-    printf("         %-7s at 0 range %3d .. %3d;\n",name,low,high); 
+    printf("         %-7s at 0 range %3d .. %3d;\n",name,low,high);
 }
 
 
@@ -222,55 +219,91 @@ static void gen_mrep_rep(const char *name)
 
 static void gen_attr_set( const char *name )
 {
+  /* All of the A_xxx symbols are defined in ncurses, but not all are nonzero
+   * if "configure --enable-widec" is specified.
+   */
   static const name_attribute_pair nap[] = {
-#ifdef A_STANDOUT
+#if A_STANDOUT
     {"Stand_Out",               A_STANDOUT},
 #endif
-#ifdef A_UNDERLINE
+#if A_UNDERLINE
     {"Under_Line",              A_UNDERLINE},
 #endif
-#ifdef A_REVERSE
+#if A_REVERSE
     {"Reverse_Video",           A_REVERSE},
 #endif
-#ifdef A_BLINK
+#if A_BLINK
     {"Blink",                   A_BLINK},
 #endif
-#ifdef A_DIM
+#if A_DIM
     {"Dim_Character",           A_DIM},
 #endif
-#ifdef A_BOLD
+#if A_BOLD
     {"Bold_Character",          A_BOLD},
 #endif
-#ifdef A_ALTCHARSET
+#if A_ALTCHARSET
     {"Alternate_Character_Set", A_ALTCHARSET},
 #endif
-#ifdef A_INVIS
+#if A_INVIS
     {"Invisible_Character",     A_INVIS},
 #endif
-#ifdef A_PROTECT
+#if A_PROTECT
     {"Protected_Character",     A_PROTECT},
 #endif
-#ifdef A_HORIZONTAL
+#if A_HORIZONTAL
     {"Horizontal",              A_HORIZONTAL},
 #endif
-#ifdef A_LEFT
+#if A_LEFT
     {"Left",                    A_LEFT},
 #endif
-#ifdef A_LOW
+#if A_LOW
     {"Low",                     A_LOW},
 #endif
-#ifdef A_RIGHT
+#if A_RIGHT
     {"Right",                   A_RIGHT},
 #endif
-#ifdef A_TOP
+#if A_TOP
     {"Top",                     A_TOP},
 #endif
-#ifdef A_VERTICAL
+#if A_VERTICAL
     {"Vertical",                A_VERTICAL},
 #endif
     {(char *)0,                 0}
   };
-  gen_reps (nap, name, sizeof(int)/2);
+  chtype attr = A_ATTRIBUTES & ~A_COLOR;
+  int start=-1, len=0, i, set;
+  for(i=0;i<(int)(8*sizeof(chtype));i++) {
+    set = attr&1;
+    if (set) {
+      if (start<0)
+       start = i;
+      if (start>=0) {
+       len++;
+      }
+    }
+    attr = attr >> 1;
+  }
+  gen_reps (nap, name, (len+7)/8, little_endian?start:0);
+}
+
+static void gen_trace(const char *name)
+{  
+  static const name_attribute_pair nap[] = {
+    {"Times",               TRACE_TIMES},
+    {"Tputs",               TRACE_TPUTS},
+    {"Update",              TRACE_UPDATE},
+    {"Cursor_Move",         TRACE_MOVE},
+    {"Character_Output",    TRACE_CHARPUT},
+    {"Calls",               TRACE_CALLS},
+    {"Virtual_Puts",        TRACE_VIRTPUT},
+    {"Input_Events",        TRACE_IEVENT},
+    {"TTY_State",           TRACE_BITS},
+    {"Internal_Calls",      TRACE_ICALLS},
+    {"Character_Calls",     TRACE_CCALLS},
+    {"Termcap_TermInfo",    TRACE_DATABASE},
+    {(char *)0,                0}
+  };
+  gen_reps(nap,name,sizeof(int),0);
 }
 
 static void gen_menu_opt_rep(const char *name)
@@ -296,7 +329,7 @@ static void gen_menu_opt_rep(const char *name)
 #endif
     {(char *)0, 0}
   };
-  gen_reps (nap, name, sizeof(int));
+  gen_reps (nap, name, sizeof(int),0);
 }
 
 static void gen_item_opt_rep(const char *name)
@@ -306,8 +339,8 @@ static void gen_item_opt_rep(const char *name)
     {"Selectable", O_SELECTABLE},
 #endif
     {(char *)0   , 0}
-  };  
-  gen_reps (nap, name, sizeof(int));
+  };
+  gen_reps (nap, name, sizeof(int),0);
 }
 
 static void gen_form_opt_rep(const char *name)
@@ -321,9 +354,12 @@ static void gen_form_opt_rep(const char *name)
 #endif
     {(char *)0    , 0}
   };
-  gen_reps (nap, name, sizeof(int));
+  gen_reps (nap, name, sizeof(int),0);
 }
 
+/*
+ * Generate the representation clause for the Field_Option_Set record
+ */
 static void gen_field_opt_rep(const char *name)
 {
   static const name_attribute_pair nap[] = {
@@ -359,22 +395,34 @@ static void gen_field_opt_rep(const char *name)
 #endif
     {(char *)0, 0}
   };
-  gen_reps (nap, name, sizeof(int));
+  gen_reps (nap, name, sizeof(int),0);
 }
 
+/*
+ * Generate a single key code constant definition.
+ */
 static void keydef(const char *name, const char *old_name, int value, int mode)
 {
-  if (mode==0)
+  if (mode==0) /* Generate the new name */
     printf("   %-30s : constant Special_Key_Code := 8#%3o#;\n",name,value);
   else
-    {
+    { /* generate the old name, but only if it doesn't conflict with the old
+       * name (Ada95 isn't case sensitive!)
+       */
       const char *s = old_name; const char *t = name;
       while ( *s && *t && (toupper(*s++) == toupper(*t++)));
       if (*s || *t)
        printf("   %-16s : Special_Key_Code renames %s;\n",old_name,name);
     }
 }
-  
+
+/*
+ * Generate constants for the key codes. When called with mode==0, a
+ * complete list with nice constant names in proper casing style will
+ * be generated. Otherwise a list of old (i.e. C-style) names will be
+ * generated, given that the name wasn't already defined in the "nice"
+ * list.
+ */
 static void gen_keydefs (int mode)
 {
   char buf[16];
@@ -664,9 +712,17 @@ static void gen_keydefs (int mode)
 #endif
 #ifdef KEY_MOUSE
   keydef("Key_Mouse","KEY_MOUSE",KEY_MOUSE,mode);
-#endif  
+#endif
+#ifdef KEY_RESIZE
+  keydef("Key_Resize","KEY_RESIZE",KEY_RESIZE,mode);
+#endif
 }
 
+/*
+ * Generate a constant with the given name. The second parameter
+ * is a reference to the ACS character in the acs_map[] array and
+ * will be translated into an index.
+ */
 static void acs_def (const char *name, chtype *a)
 {
   int c = a - &acs_map[0];
@@ -677,7 +733,9 @@ static void acs_def (const char *name, chtype *a)
     printf("Character'Val (%d);\n",c);
 }
 
-
+/*
+ * Generate the constants for the ACS characters
+ */
 static void gen_acs (void)
 {
 #ifdef ACS_ULCORNER
@@ -778,16 +836,160 @@ static void gen_acs (void)
 #endif
 }
 
+
+#define GEN_EVENT(name,value) \
+   printf("   %-25s : constant Event_Mask := 8#%011lo#;\n", \
+          #name, value)
+
+#define GEN_MEVENT(name) \
+   printf("   %-25s : constant Event_Mask := 8#%011lo#;\n", \
+          #name, name)
+
+static
+void gen_mouse_events(void)
+{
+  mmask_t all1 = 0;
+  mmask_t all2 = 0;
+  mmask_t all3 = 0;
+  mmask_t all4 = 0;
+
+#ifdef BUTTON1_RELEASED
+  GEN_MEVENT(BUTTON1_RELEASED);
+  all1 |= BUTTON1_RELEASED;
+#endif
+#ifdef BUTTON1_PRESSED
+  GEN_MEVENT(BUTTON1_PRESSED);
+  all1 |= BUTTON1_PRESSED;
+#endif
+#ifdef BUTTON1_CLICKED
+  GEN_MEVENT(BUTTON1_CLICKED);
+  all1 |= BUTTON1_CLICKED;
+#endif
+#ifdef BUTTON1_DOUBLE_CLICKED
+  GEN_MEVENT(BUTTON1_DOUBLE_CLICKED);
+  all1 |= BUTTON1_DOUBLE_CLICKED;
+#endif
+#ifdef BUTTON1_TRIPLE_CLICKED
+  GEN_MEVENT(BUTTON1_TRIPLE_CLICKED);
+  all1 |= BUTTON1_TRIPLE_CLICKED;
+#endif
+#ifdef BUTTON1_RESERVED_EVENT
+  GEN_MEVENT(BUTTON1_RESERVED_EVENT);
+  all1 |= BUTTON1_RESERVED_EVENT;
+#endif
+#ifdef BUTTON2_RELEASED
+  GEN_MEVENT(BUTTON2_RELEASED);
+  all2 |= BUTTON2_RELEASED;
+#endif
+#ifdef BUTTON2_PRESSED
+  GEN_MEVENT(BUTTON2_PRESSED);
+  all2 |= BUTTON2_PRESSED;
+#endif
+#ifdef BUTTON2_CLICKED
+  GEN_MEVENT(BUTTON2_CLICKED);
+  all2 |= BUTTON2_CLICKED;
+#endif
+#ifdef BUTTON2_DOUBLE_CLICKED
+  GEN_MEVENT(BUTTON2_DOUBLE_CLICKED);
+  all2 |= BUTTON2_DOUBLE_CLICKED;
+#endif
+#ifdef BUTTON2_TRIPLE_CLICKED
+  GEN_MEVENT(BUTTON2_TRIPLE_CLICKED);
+  all2 |= BUTTON2_TRIPLE_CLICKED;
+#endif
+#ifdef BUTTON2_RESERVED_EVENT
+  GEN_MEVENT(BUTTON2_RESERVED_EVENT);
+  all2 |= BUTTON2_RESERVED_EVENT;
+#endif
+#ifdef BUTTON3_RELEASED
+  GEN_MEVENT(BUTTON3_RELEASED);
+  all3 |= BUTTON3_RELEASED;
+#endif
+#ifdef BUTTON3_PRESSED
+  GEN_MEVENT(BUTTON3_PRESSED);
+  all3 |= BUTTON3_PRESSED;
+#endif
+#ifdef BUTTON3_CLICKED
+  GEN_MEVENT(BUTTON3_CLICKED);
+  all3 |= BUTTON3_CLICKED;
+#endif
+#ifdef BUTTON3_DOUBLE_CLICKED
+  GEN_MEVENT(BUTTON3_DOUBLE_CLICKED);
+  all3 |= BUTTON3_DOUBLE_CLICKED;
+#endif
+#ifdef BUTTON3_TRIPLE_CLICKED
+  GEN_MEVENT(BUTTON3_TRIPLE_CLICKED);
+  all3 |= BUTTON3_TRIPLE_CLICKED;
+#endif
+#ifdef BUTTON3_RESERVED_EVENT
+  GEN_MEVENT(BUTTON3_RESERVED_EVENT);
+  all3 |= BUTTON3_RESERVED_EVENT;
+#endif
+#ifdef BUTTON4_RELEASED
+  GEN_MEVENT(BUTTON4_RELEASED);
+  all4 |= BUTTON4_RELEASED;
+#endif
+#ifdef BUTTON4_PRESSED
+  GEN_MEVENT(BUTTON4_PRESSED);
+  all4 |= BUTTON4_PRESSED;
+#endif
+#ifdef BUTTON4_CLICKED
+  GEN_MEVENT(BUTTON4_CLICKED);
+  all4 |= BUTTON4_CLICKED;
+#endif
+#ifdef BUTTON4_DOUBLE_CLICKED
+  GEN_MEVENT(BUTTON4_DOUBLE_CLICKED);
+  all4 |= BUTTON4_DOUBLE_CLICKED;
+#endif
+#ifdef BUTTON4_TRIPLE_CLICKED
+  GEN_MEVENT(BUTTON4_TRIPLE_CLICKED);
+  all4 |= BUTTON4_TRIPLE_CLICKED;
+#endif
+#ifdef BUTTON4_RESERVED_EVENT
+  GEN_MEVENT(BUTTON4_RESERVED_EVENT);
+  all4 |= BUTTON4_RESERVED_EVENT;
+#endif
+#ifdef BUTTON_CTRL
+  GEN_MEVENT(BUTTON_CTRL);
+#endif
+#ifdef BUTTON_SHIFT
+  GEN_MEVENT(BUTTON_SHIFT);
+#endif
+#ifdef BUTTON_ALT
+  GEN_MEVENT(BUTTON_ALT);
+#endif
+#ifdef REPORT_MOUSE_POSITION
+  GEN_MEVENT(REPORT_MOUSE_POSITION);
+#endif   
+#ifdef ALL_MOUSE_EVENTS
+  GEN_MEVENT(ALL_MOUSE_EVENTS);
+#endif
+
+GEN_EVENT(BUTTON1_EVENTS,all1);
+GEN_EVENT(BUTTON2_EVENTS,all2);
+GEN_EVENT(BUTTON3_EVENTS,all3);
+GEN_EVENT(BUTTON4_EVENTS,all4);
+}
+
+/*
+ * Output some comment lines indicating that the file is generated.
+ * The name parameter is the name of the facility to be used in
+ * the comment.
+ */
 static void prologue(const char *name)
 {
-  time_t t = time(NULL);
-  printf("--  %s binding, generated at %s",name,ctime(&t));
+  printf("--  %s binding.\n",name);
   printf("--  This module is generated. Please don't change it manually!\n");
   printf("--  Run the generator instead.\n--  |");
 
-  printf("define(`M4_BIT_ORDER',`%s_Order_First')",little_endian ? "Low":"High");
+  printf("define(`M4_BIT_ORDER',`%s_Order_First')",
+        little_endian ? "Low":"High");
 }
 
+/*
+ * Write the prologue for the curses facility and make sure that
+ * KEY_MIN and KEY_MAX are defined for the rest of this source.
+ */
 static void basedefs (void)
 {
   prologue("curses");
@@ -798,33 +1000,55 @@ static void basedefs (void)
 #ifndef KEY_MIN
 #  define KEY_MIN 0401
 #endif
-  if (KEY_MIN == 256)
-    abort();
+  if (KEY_MIN == 256) {
+    fprintf(stderr,"Unexpected value for KEY_MIN: %d\n",KEY_MIN);
+    exit(1);
+  }
   printf("define(`M4_SPECIAL_FIRST',`8#%o#')",KEY_MIN - 1);
 }
 
+/*
+ * Write out the comment lines for the menu facility
+ */
 static void menu_basedefs (void)
 {
   prologue("menu");
 }
 
+/*
+ * Write out the comment lines for the form facility
+ */
 static void form_basedefs (void)
 {
   prologue("form");
 }
 
+/*
+ * Write out the comment lines for the mouse facility
+ */
 static void mouse_basedefs(void)
 {
   prologue("mouse");
 }
 
+/*
+ * Write the definition of a single color
+ */
 static void color_def (const char *name, int value)
 {
-  printf("   %-8s : constant Color_Number := %d;\n",name,value);
+  printf("   %-16s : constant Color_Number := %d;\n",name,value);
 }
 
+#define HAVE_USE_DEFAULT_COLORS 1
+
+/*
+ * Generate all color definitions
+ */
 static void gen_color (void)
 {
+#ifdef HAVE_USE_DEFAULT_COLORS
+  color_def ("Default_Color",-1);
+#endif
 #ifdef COLOR_BLACK
   color_def ("Black",COLOR_BLACK);
 #endif
@@ -851,27 +1075,145 @@ static void gen_color (void)
 #endif
 }
 
+/*
+ * Generate the linker options for the base facility
+ */
 static void gen_linkopts (void)
 {
-   printf("   pragma Linker_Options (\"-lncurses\");\n");
+   printf("   pragma Linker_Options (\"-lncurses%s\");\n", model);
 }
 
+/*
+ * Generate the linker options for the menu facility
+ */
 static void gen_menu_linkopts (void)
 {
-   printf("   pragma Linker_Options (\"-lmenu\");\n");
+   printf("   pragma Linker_Options (\"-lmenu%s\");\n", model);
 }
 
+/*
+ * Generate the linker options for the form facility
+ */
 static void gen_form_linkopts (void)
 {
-   printf("   pragma Linker_Options (\"-lform\");\n");
+   printf("   pragma Linker_Options (\"-lform%s\");\n", model);
 }
 
+/*
+ * Generate the linker options for the panel facility
+ */
 static void gen_panel_linkopts (void)
 {
-   printf("   pragma Linker_Options (\"-lpanel\");\n");
+   printf("   pragma Linker_Options (\"-lpanel%s\");\n", model);
 }
 
+static void gen_version_info (void)
+{
+  static const char* v1 =
+    "   NC_Major_Version : constant := %d; --  Major version of the library\n";
+  static const char* v2 =
+    "   NC_Minor_Version : constant := %d; --  Minor version of the library\n";
+  static const char* v3 =
+    "   NC_Version : constant String := %c%d.%d%c;  --  Version of library\n";
+
+  printf(v1, NCURSES_VERSION_MAJOR);
+  printf(v2, NCURSES_VERSION_MINOR);
+  printf(v3, '"',NCURSES_VERSION_MAJOR,NCURSES_VERSION_MINOR,'"');
+}
+
+static int
+eti_gen(char*buf, int code, const char* name, int* etimin, int* etimax)
+{
+  sprintf(buf,"   E_%-16s : constant Eti_Error := %d;\n",name,code);
+  if (code < *etimin)
+    *etimin = code;
+  if (code > *etimax)
+    *etimax = code;
+  return strlen(buf);
+}
+
+#define GEN_OFFSET(member,itype)                                    \
+  if (sizeof(((WINDOW*)0)->member)==sizeof(itype)) {                \
+    o = offsetof(WINDOW, member);                                   \
+    if ((o%sizeof(itype) == 0)) {                                   \
+       printf("   Offset%-*s : constant Natural := %2ld; --  %s\n", \
+              12, #member, o/sizeof(itype),#itype);                 \
+    }                                                               \
+  }
+  
+static void
+gen_offsets(void)
+{
+  long o;
+  const char* s_bool = "";
+
+  GEN_OFFSET(_maxy,short);
+  GEN_OFFSET(_maxx,short);
+  GEN_OFFSET(_begy,short);
+  GEN_OFFSET(_begx,short);
+  GEN_OFFSET(_cury,short);
+  GEN_OFFSET(_curx,short);
+  GEN_OFFSET(_yoffset,short);
+  GEN_OFFSET(_pary,int);
+  GEN_OFFSET(_parx,int);
+  if (sizeof(bool) == sizeof(char)) {
+    GEN_OFFSET(_notimeout,char);
+    GEN_OFFSET(_clear,char);
+    GEN_OFFSET(_leaveok,char);
+    GEN_OFFSET(_scroll,char);
+    GEN_OFFSET(_idlok,char);
+    GEN_OFFSET(_idcok,char);
+    GEN_OFFSET(_immed,char);
+    GEN_OFFSET(_sync,char);
+    GEN_OFFSET(_use_keypad,char);
+    s_bool = "char";
+  } else if (sizeof(bool) == sizeof(short)) {
+    GEN_OFFSET(_notimeout,short);
+    GEN_OFFSET(_clear,short);
+    GEN_OFFSET(_leaveok,short);
+    GEN_OFFSET(_scroll,short);
+    GEN_OFFSET(_idlok,short);
+    GEN_OFFSET(_idcok,short);
+    GEN_OFFSET(_immed,short);
+    GEN_OFFSET(_sync,short);
+    GEN_OFFSET(_use_keypad,short);
+    s_bool = "short";
+  } else if (sizeof(bool) == sizeof(int)) {
+    GEN_OFFSET(_notimeout,int);
+    GEN_OFFSET(_clear,int);
+    GEN_OFFSET(_leaveok,int);
+    GEN_OFFSET(_scroll,int);
+    GEN_OFFSET(_idlok,int);
+    GEN_OFFSET(_idcok,int);
+    GEN_OFFSET(_immed,int);
+    GEN_OFFSET(_sync,int);
+    GEN_OFFSET(_use_keypad,int);
+    s_bool = "int";
+  }
+  printf("   Sizeof%-*s : constant Natural := %2ld; --  %s\n",
+        12, "_bool", (long) sizeof(bool),"bool");
+  /* In ncurses _maxy and _maxx needs an offset for the "public"
+   * value
+   */
+  printf("   Offset%-*s : constant Natural := %2d; --  %s\n",
+        12, "_XY",1,"int");
+  printf("\n");
+  printf("   type Curses_Bool is mod 2 ** Interfaces.C.%s'Size;\n",s_bool);
+}
 
+/*
+ * main() expects two arguments on the commandline, both single characters.
+ * The first character denotes the facility for which we generate output.
+ * Possible values are
+ *   B - Base
+ *   M - Menus
+ *   F - Forms
+ *   P - Pointer Device (Mouse)
+ *   E - ETI base definitions
+ *
+ * The second character then denotes the specific output that should be
+ * generated for the selected facility.
+ */
 int main(int argc, char *argv[])
 {
   int x = 0x12345678;
@@ -880,98 +1222,216 @@ int main(int argc, char *argv[])
   if (*s == 0x78)
     little_endian = 1;
 
-  if (argc!=3)
+  if (argc!=4)
     exit(1);
+  model = *++argv;
 
   switch(argv[1][0])
     {
-    case 'B':
+      /* ---------------------------------------------------------------*/   
+    case 'B': /* The Base facility */
       switch(argv[2][0])
        {
-       case 'A':
+       case 'A': /* chtype translation into Ada95 record type */
          gen_attr_set("Character_Attribute_Set");
          break;
-       case 'K':
+       case 'K': /* translation of keycodes */
          gen_keydefs(0);
          break;
-       case 'B':
+       case 'B': /* write some initial comment lines */
          basedefs();
          break;
-       case 'C':
+       case 'C': /* generate color constants */
          gen_color();
          break;
-       case 'M':
+       case 'D': /* generate displacements of fields in WINDOW struct. */
+         gen_offsets();
+         break;
+       case 'E': /* generate Mouse Event codes */
+         gen_mouse_events();
+         break;
+       case 'M': /* generate constants for the ACS characters */
          gen_acs();
          break;
-       case 'L':
+       case 'L': /* generate the Linker_Options pragma */
          gen_linkopts();
          break;
-       case 'O':
+       case 'O': /* generate definitions of the old key code names */
          gen_keydefs(1);
          break;
-       case 'R':
+       case 'R': /* generate representation clause for Attributed character */
          gen_chtype_rep("Attributed_Character");
          break;
+       case 'V': /* generate version info */
+         gen_version_info();
+         break;
+       case 'T': /* generate the Trace info */
+         gen_trace("Trace_Attribute_Set");
+         break;
        default:
          break;
        }
       break;
-    case 'M':
+      /* ---------------------------------------------------------------*/   
+    case 'M': /* The Menu facility */
       switch(argv[2][0])
        {
-       case 'R':
+       case 'R': /* generate representation clause for Menu_Option_Set */
          gen_menu_opt_rep("Menu_Option_Set");
          break;
-       case 'B':
+       case 'B': /* write some initial comment lines */
          menu_basedefs();
          break;
-       case 'L':
+       case 'L': /* generate the Linker_Options pragma */
          gen_menu_linkopts();
          break;
-       case 'I':
+       case 'I': /* generate representation clause for Item_Option_Set */
          gen_item_opt_rep("Item_Option_Set");
          break;
        default:
          break;
        }
       break;
-    case 'F':
+      /* ---------------------------------------------------------------*/   
+    case 'F': /* The Form facility */
       switch(argv[2][0])
        {
-       case 'R':
+       case 'R': /* generate representation clause for Form_Option_Set */
          gen_form_opt_rep("Form_Option_Set");
          break;
-       case 'B':
+       case 'B': /* write some initial comment lines */
          form_basedefs();
          break;
-       case 'L':
+       case 'L': /* generate the Linker_Options pragma */
          gen_form_linkopts();
          break;
-       case 'I':
+       case 'I': /* generate representation clause for Field_Option_Set */
          gen_field_opt_rep("Field_Option_Set");
          break;
        default:
          break;
        }
       break;
-    case 'P':
-      switch(argv[2][0])
-       {
-       case 'B':
+      /* ---------------------------------------------------------------*/   
+    case 'P': /* The Pointer(=Mouse) facility */
+      switch(argv[2][0]) {
+       case 'B': /* write some initial comment lines */
          mouse_basedefs();
          break;
-       case 'M':
+       case 'M': /* generate representation clause for Mouse_Event */
          gen_mrep_rep("Mouse_Event");
          break;
-       case 'L':
+       case 'L': /* generate the Linker_Options pragma */
          gen_panel_linkopts();
          break;
        default:
          break;
        }
        break;
+      /* ---------------------------------------------------------------*/   
+    case 'E' : /* chtype size detection */
+      switch(argv[2][0]) {
+      case 'C':
+       {
+         const char* fmt  = "   type    C_Chtype   is new %s;\n";
+         const char* afmt = "   type    C_AttrType is new %s;\n";
+
+         if (sizeof(chtype)==sizeof(int)) {
+           if (sizeof(int)==sizeof(long))
+             printf(fmt,"C_ULong");
+           else
+             printf(fmt,"C_UInt");
+         }
+         else if (sizeof(chtype)==sizeof(long)) {
+           printf(fmt,"C_ULong");
+         }
+         else
+           printf("Error\n");
+
+         if (sizeof(attr_t)==sizeof(int)) {
+           if (sizeof(int)==sizeof(long))
+             printf(afmt,"C_ULong");
+           else
+             printf(afmt,"C_UInt");
+         }
+         else if (sizeof(attr_t)==sizeof(long)) {
+           printf(afmt,"C_ULong");
+         }
+         else
+           printf("Error\n");
+
+         printf("define(`CF_CURSES_OK',`%d')",OK);
+         printf("define(`CF_CURSES_ERR',`%d')",ERR);
+         printf("define(`CF_CURSES_TRUE',`%d')",TRUE);
+         printf("define(`CF_CURSES_FALSE',`%d')",FALSE);
+       }
+       break;
+      case 'E':
+       {
+         char* buf  = (char*)malloc(2048);
+         char* p    = buf;
+         int etimin = E_OK;
+         int etimax = E_OK;
+         if (p) {
+           p += eti_gen(p, E_OK, "Ok", &etimin, &etimax);
+           p += eti_gen(p, E_SYSTEM_ERROR,"System_Error", &etimin, &etimax);
+           p += eti_gen(p, E_BAD_ARGUMENT, "Bad_Argument", &etimin, &etimax);
+           p += eti_gen(p, E_POSTED, "Posted", &etimin, &etimax);
+           p += eti_gen(p, E_CONNECTED, "Connected", &etimin, &etimax);
+           p += eti_gen(p, E_BAD_STATE, "Bad_State", &etimin, &etimax);
+           p += eti_gen(p, E_NO_ROOM, "No_Room", &etimin, &etimax);
+           p += eti_gen(p, E_NOT_POSTED, "Not_Posted", &etimin, &etimax);
+           p += eti_gen(p, E_UNKNOWN_COMMAND,
+                        "Unknown_Command", &etimin, &etimax);
+           p += eti_gen(p, E_NO_MATCH, "No_Match", &etimin, &etimax);
+           p += eti_gen(p, E_NOT_SELECTABLE,
+                        "Not_Selectable", &etimin, &etimax);
+           p += eti_gen(p, E_NOT_CONNECTED,
+                        "Not_Connected", &etimin, &etimax);
+           p += eti_gen(p, E_REQUEST_DENIED,
+                        "Request_Denied", &etimin, &etimax);
+           p += eti_gen(p, E_INVALID_FIELD,
+                        "Invalid_Field", &etimin, &etimax);
+           p += eti_gen(p, E_CURRENT,
+                        "Current", &etimin, &etimax);
+         }
+         printf("   subtype Eti_Error is C_Int range %d .. %d;\n\n",
+                etimin,etimax);
+         printf(buf);
+       }
+       break;
+      default:
+       break;
+      }
+      break;
+      /* ---------------------------------------------------------------*/   
+    case 'V' : /* plain version dump */
+      {
+       switch(argv[2][0]) {
+       case '1': /* major version */
+#ifdef NCURSES_VERSION_MAJOR
+         printf("%d",NCURSES_VERSION_MAJOR);
+#endif
+         break;
+       case '2': /* minor version */
+#ifdef NCURSES_VERSION_MINOR
+         printf("%d",NCURSES_VERSION_MINOR);
+#endif
+         break;
+       case '3': /* patch level */
+#ifdef NCURSES_VERSION_PATCH
+         printf("%d",NCURSES_VERSION_PATCH);
+#endif
+         break;
+       default:
+         break;
+       }
+      }
+      break;
+      /* ---------------------------------------------------------------*/     
     default:
       break;
     }
   return 0;
 }
+