Re: -fdump-go-spec option does not handle redefinitions

2011-11-02 Thread Uros Bizjak
On Wed, Nov 2, 2011 at 6:06 AM, Ian Lance Taylor i...@google.com wrote:

 The problem with your proposal is that the output would be invalid Go,
 because it would attempt to define the name _aa twice.  However, it does
 seem plausible that in most scenarios of this type it would be more
 useful for -fdump-go-spec to generate

 const _aa = 3

 I agree.

 This patch implements this approach.  Bootstrapped and ran Go testsuite
 on x86_64-unknown-linux-gnu.  Committed to mainline.

Thanks, bu this is still not enough to determine corretc IOCTL number :(

#defines with arguments are not working at all. Please consider
following testcase:

--cut here--
#define _IOC_NRBITS8
#define _IOC_TYPEBITS  8
#define _IOC_SIZEBITS  13
#define _IOC_DIRBITS   3

#define _IOC_NRMASK((1  _IOC_NRBITS)-1)
#define _IOC_TYPEMASK  ((1  _IOC_TYPEBITS)-1)
#define _IOC_SIZEMASK  ((1  _IOC_SIZEBITS)-1)
#define _IOC_DIRMASK   ((1  _IOC_DIRBITS)-1)

#define _IOC_NRSHIFT   0
#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
#define _IOC_DIRSHIFT  (_IOC_SIZESHIFT+_IOC_SIZEBITS)

/*
 * Direction bits _IOC_NONE could be 0, but OSF/1 gives it a bit.
 * And this turns out useful to catch old ioctl numbers in header
 * files for us.
 */
#define _IOC_NONE  1U
#define _IOC_READ  2U
#define _IOC_WRITE 3U

#define _IOC(dir,type,nr,size)  \
  ((unsigned int)   \
   (((dir)   _IOC_DIRSHIFT) | \
((type)  _IOC_TYPESHIFT) |\
((nr)_IOC_NRSHIFT) |  \
((size)  _IOC_SIZESHIFT)))

/* used to create numbers */
#define _IO(type,nr)   _IOC(_IOC_NONE,(type),(nr),0)
#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))

#define FIOCLEX _IO('f', 1)
#define FIONCLEX_IO('f', 2)

#define TCGETS  _IOR('t', 19, struct termios)
#define TCSETS  _IOW('t', 20, struct termios)
--cut here--

Resulting -fdump-go-spec file:

...
const __IOC_NRSHIFT = 0
const __IOC_TYPESHIFT = (__IOC_NRSHIFT+__IOC_NRBITS)
const __IOC_SIZESHIFT = (__IOC_TYPESHIFT+__IOC_TYPEBITS)
const __IOC_DIRSHIFT = (__IOC_SIZESHIFT+__IOC_SIZEBITS)
const __IOC_NONE = 1
const __IOC_READ = 2
const __IOC_WRITE = 3
// unknowndefine FIOCLEX _IO('f', 1)
// unknowndefine FIONCLEX _IO('f', 2)
// unknowndefine TCGETS _IOR('t', 19, struct termios)
// unknowndefine TCSETS _IOW('t', 20, struct termios)

Please note missing struct terminfos define, so I understand that
TC[GS]ETS is unknown, but FIOCLEX should be fully defined by
preceeding definitions.

Uros.


Re: -fdump-go-spec option does not handle redefinitions

2011-11-02 Thread Ian Lance Taylor
Uros Bizjak ubiz...@gmail.com writes:

 #defines with arguments are not working at all. Please consider
 following testcase:

You're right: this approach doesn't work for preprocessor macros with
arguments.  Making those work via this approach would be much much
harder.

 Please note missing struct terminfos define, so I understand that
 TC[GS]ETS is unknown, but FIOCLEX should be fully defined by
 preceeding definitions.

Fortunately, the value of FIOCLEX is irrelevant.  And as you say, this
approach can't work for TCGETS anyhow.

So let's take a different approach.  This patch drops the use of TCGETS
and TCSETS entirely.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian

diff -r 39e671bf216d libgo/go/exp/terminal/terminal.go
--- a/libgo/go/exp/terminal/terminal.go	Wed Nov 02 08:58:28 2011 -0700
+++ b/libgo/go/exp/terminal/terminal.go	Wed Nov 02 09:42:23 2011 -0700
@@ -17,7 +17,6 @@
 import (
 	os
 	syscall
-	unsafe
 )
 
 // State contains the state of a terminal.
@@ -28,7 +27,7 @@
 // IsTerminal returns true if the given file descriptor is a terminal.
 func IsTerminal(fd int) bool {
 	var termios syscall.Termios
-	_, _, e := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCGETS), uintptr(unsafe.Pointer(termios)), 0, 0, 0)
+	e := syscall.Tcgetattr(fd, termios)
 	return e == 0
 }
 
@@ -37,14 +36,14 @@
 // restored.
 func MakeRaw(fd int) (*State, os.Error) {
 	var oldState State
-	if _, _, e := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCGETS), uintptr(unsafe.Pointer(oldState.termios)), 0, 0, 0); e != 0 {
+	if e := syscall.Tcgetattr(fd, oldState.termios); e != 0 {
 		return nil, os.Errno(e)
 	}
 
 	newState := oldState.termios
 	newState.Iflag ^= syscall.ISTRIP | syscall.INLCR | syscall.ICRNL | syscall.IGNCR | syscall.IXON | syscall.IXOFF
 	newState.Lflag ^= syscall.ECHO | syscall.ICANON | syscall.ISIG
-	if _, _, e := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(newState)), 0, 0, 0); e != 0 {
+	if e := syscall.Tcsetattr(fd, syscall.TCSANOW, newState); e != 0 {
 		return nil, os.Errno(e)
 	}
 
@@ -54,7 +53,7 @@
 // Restore restores the terminal connected to the given file descriptor to a
 // previous state.
 func Restore(fd int, state *State) os.Error {
-	_, _, e := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(state.termios)), 0, 0, 0)
+	e := syscall.Tcsetattr(fd, syscall.TCSANOW, state.termios)
 	return os.Errno(e)
 }
 
@@ -63,18 +62,18 @@
 // returned does not include the \n.
 func ReadPassword(fd int) ([]byte, os.Error) {
 	var oldState syscall.Termios
-	if _, _, e := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCGETS), uintptr(unsafe.Pointer(oldState)), 0, 0, 0); e != 0 {
+	if e := syscall.Tcgetattr(fd, oldState); e != 0 {
 		return nil, os.Errno(e)
 	}
 
 	newState := oldState
 	newState.Lflag ^= syscall.ECHO
-	if _, _, e := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(newState)), 0, 0, 0); e != 0 {
+	if e := syscall.Tcsetattr(fd, syscall.TCSANOW, newState); e != 0 {
 		return nil, os.Errno(e)
 	}
 
 	defer func() {
-		syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(oldState)), 0, 0, 0)
+		syscall.Tcsetattr(fd, syscall.TCSANOW, oldState)
 	}()
 
 	var buf [16]byte
diff -r 39e671bf216d libgo/go/syscall/libcall_posix.go
--- a/libgo/go/syscall/libcall_posix.go	Wed Nov 02 08:58:28 2011 -0700
+++ b/libgo/go/syscall/libcall_posix.go	Wed Nov 02 09:42:23 2011 -0700
@@ -377,3 +377,9 @@
 	tv.Usec = Timeval_usec_t(nsec % 1e9 / 1e3)
 	return
 }
+
+//sysnb	Tcgetattr(fd int, p *Termios) (errno int)
+//tcgetattr(fd int, p *Termios) int
+
+//sys	Tcsetattr(fd int, actions int, p *Termios) (errno int)
+//tcsetattr(fd int, actions int, p *Termios) int


Re: -fdump-go-spec option does not handle redefinitions

2011-11-01 Thread Ian Lance Taylor
Uros Bizjak ubiz...@gmail.com writes:

 The problem with your proposal is that the output would be invalid Go,
 because it would attempt to define the name _aa twice.  However, it does
 seem plausible that in most scenarios of this type it would be more
 useful for -fdump-go-spec to generate

 const _aa = 3

 I agree.

This patch implements this approach.  Bootstrapped and ran Go testsuite
on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian


2011-11-01  Ian Lance Taylor  i...@google.com

* godump.c (struct macro_hash_value): Define.
(macro_hash_hashval): New static function.
(macro_hash_eq, macro_hash_del): New static functions.
(go_define): Use macro_hash_value to store values in macro_hash.
Replace an old value on a redefinition.  Don't print anything to
go_dump_file.
(go_undef): Delete the entry from the hash table.
(go_output_typedef): For an enum, use macro_hash_value, and don't
print anything to go_dump_file.
(go_print_macro): New static function.
(go_finish): Traverse macro_hash with go_print_macro.
(dump_go_spec_init): Update macro_hash creation for
macro_hash_value.


Index: godump.c
===
--- godump.c	(revision 180342)
+++ godump.c	(working copy)
@@ -62,7 +62,47 @@ static GTY(()) VEC(tree,gc) *queue;
 
 static htab_t macro_hash;
 
-/* For the hash tables.  */
+/* The type of a value in macro_hash.  */
+
+struct macro_hash_value
+{
+  /* The name stored in the hash table.  */
+  char *name;
+  /* The value of the macro.  */
+  char *value;
+};
+
+/* Calculate the hash value for an entry in the macro hash table.  */
+
+static hashval_t
+macro_hash_hashval (const void *val)
+{
+  const struct macro_hash_value *mhval = (const struct macro_hash_value *) val;
+  return htab_hash_string (mhval-name);
+}
+
+/* Compare values in the macro hash table for equality.  */
+
+static int
+macro_hash_eq (const void *v1, const void *v2)
+{
+  const struct macro_hash_value *mhv1 = (const struct macro_hash_value *) v1;
+  const struct macro_hash_value *mhv2 = (const struct macro_hash_value *) v2;
+  return strcmp (mhv1-name, mhv2-name) == 0;
+}
+
+/* Free values deleted from the macro hash table.  */
+
+static void
+macro_hash_del (void *v)
+{
+  struct macro_hash_value *mhv = (struct macro_hash_value *) v;
+  XDELETEVEC (mhv-name);
+  XDELETEVEC (mhv-value);
+  XDELETE (mhv);
+}
+
+/* For the string hash tables.  */
 
 static int
 string_hash_eq (const void *y1, const void *y2)
@@ -77,10 +117,12 @@ go_define (unsigned int lineno, const ch
 {
   const char *p;
   const char *name_end;
+  size_t out_len;
   char *out_buffer;
   char *q;
   bool saw_operand;
   bool need_operand;
+  struct macro_hash_value *mhval;
   char *copy;
   hashval_t hashval;
   void **slot;
@@ -105,17 +147,17 @@ go_define (unsigned int lineno, const ch
   memcpy (copy, buffer, name_end - buffer);
   copy[name_end - buffer] = '\0';
 
+  mhval = XNEW (struct macro_hash_value);
+  mhval-name = copy;
+  mhval-value = NULL;
+
   hashval = htab_hash_string (copy);
-  slot = htab_find_slot_with_hash (macro_hash, copy, hashval, NO_INSERT);
-  if (slot != NULL)
-{
-  XDELETEVEC (copy);
-  return;
-}
+  slot = htab_find_slot_with_hash (macro_hash, mhval, hashval, NO_INSERT);
 
   /* For simplicity, we force all names to be hidden by adding an
  initial underscore, and let the user undo this as needed.  */
-  out_buffer = XNEWVEC (char, strlen (p) * 2 + 1);
+  out_len = strlen (p) * 2 + 1;
+  out_buffer = XNEWVEC (char, out_len);
   q = out_buffer;
   saw_operand = false;
   need_operand = false;
@@ -141,6 +183,7 @@ go_define (unsigned int lineno, const ch
 	   don't worry about them.  */
 	const char *start;
 	char *n;
+	struct macro_hash_value idval;
 
 	if (saw_operand)
 	  goto unknown;
@@ -151,8 +194,9 @@ go_define (unsigned int lineno, const ch
 	n = XALLOCAVEC (char, p - start + 1);
 	memcpy (n, start, p - start);
 	n[p - start] = '\0';
-	slot = htab_find_slot (macro_hash, n, NO_INSERT);
-	if (slot == NULL || *slot == NULL)
+	idval.name = n;
+	idval.value = NULL;
+	if (htab_find (macro_hash, idval) == NULL)
 	  {
 		/* This is a reference to a name which was not defined
 		   as a macro.  */
@@ -382,18 +426,30 @@ go_define (unsigned int lineno, const ch
   if (need_operand)
 goto unknown;
 
+  gcc_assert ((size_t) (q - out_buffer)  out_len);
   *q = '\0';
 
-  slot = htab_find_slot_with_hash (macro_hash, copy, hashval, INSERT);
-  *slot = copy;
+  mhval-value = out_buffer;
 
-  fprintf (go_dump_file, const _%s = %s\n, copy, out_buffer);
+  if (slot == NULL)
+{
+  slot = htab_find_slot_with_hash (macro_hash, mhval, hashval, INSERT);
+  gcc_assert (slot != NULL  *slot == NULL);
+}
+  else
+{
+  if (*slot != NULL)
+	macro_hash_del (*slot);
+}
+
+  *slot = mhval;
 
-