runtime: Copy runtime_printf from other Go library.
authorIan Lance Taylor <ian@gcc.gnu.org>
Thu, 24 May 2012 20:45:37 +0000 (20:45 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Thu, 24 May 2012 20:45:37 +0000 (20:45 +0000)
From-SVN: r187850

libgo/runtime/print.c [new file with mode: 0644]

diff --git a/libgo/runtime/print.c b/libgo/runtime/print.c
new file mode 100644 (file)
index 0000000..3eafeb7
--- /dev/null
@@ -0,0 +1,310 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <stdarg.h>
+#include "runtime.h"
+
+//static Lock debuglock;
+
+static void go_vprintf(const char*, va_list);
+
+// write to goroutine-local buffer if diverting output,
+// or else standard error.
+static void
+gwrite(const void *v, int32 n)
+{
+       G* g = runtime_g();
+
+       if(g == nil || g->writebuf == nil) {
+               runtime_write(2, v, n);
+               return;
+       }
+       
+       if(g->writenbuf == 0)
+               return;
+       
+       if(n > g->writenbuf)
+               n = g->writenbuf;
+       runtime_memmove(g->writebuf, v, n);
+       g->writebuf += n;
+       g->writenbuf -= n;
+}
+
+void
+runtime_dump(byte *p, int32 n)
+{
+       int32 i;
+
+       for(i=0; i<n; i++) {
+               runtime_printpointer((byte*)(uintptr)(p[i]>>4));
+               runtime_printpointer((byte*)(uintptr)(p[i]&0xf));
+               if((i&15) == 15)
+                       runtime_prints("\n");
+               else
+                       runtime_prints(" ");
+       }
+       if(n & 15)
+               runtime_prints("\n");
+}
+
+void
+runtime_prints(const char *s)
+{
+       gwrite(s, runtime_findnull((const byte*)s));
+}
+
+void
+runtime_printf(const char *s, ...)
+{
+       va_list va;
+
+       va_start(va, s);
+       go_vprintf(s, va);
+       va_end(va);
+}
+
+// Very simple printf.  Only for debugging prints.
+// Do not add to this without checking with Rob.
+static void
+go_vprintf(const char *s, va_list va)
+{
+       const char *p, *lp;
+
+       //runtime_lock(&debuglock);
+
+       lp = p = s;
+       for(; *p; p++) {
+               if(*p != '%')
+                       continue;
+               if(p > lp)
+                       gwrite(lp, p-lp);
+               p++;
+               switch(*p) {
+               case 'a':
+                       runtime_printslice(va_arg(va, Slice));
+                       break;
+               case 'd':
+                       runtime_printint(va_arg(va, int32));
+                       break;
+               case 'D':
+                       runtime_printint(va_arg(va, int64));
+                       break;
+               case 'e':
+                       runtime_printeface(va_arg(va, Eface));
+                       break;
+               case 'f':
+                       runtime_printfloat(va_arg(va, float64));
+                       break;
+               case 'C':
+                       runtime_printcomplex(va_arg(va, __complex double));
+                       break;
+               case 'i':
+                       runtime_printiface(va_arg(va, Iface));
+                       break;
+               case 'p':
+                       runtime_printpointer(va_arg(va, void*));
+                       break;
+               case 's':
+                       runtime_prints(va_arg(va, char*));
+                       break;
+               case 'S':
+                       runtime_printstring(va_arg(va, String));
+                       break;
+               case 't':
+                       runtime_printbool(va_arg(va, int));
+                       break;
+               case 'U':
+                       runtime_printuint(va_arg(va, uint64));
+                       break;
+               case 'x':
+                       runtime_printhex(va_arg(va, uint32));
+                       break;
+               case 'X':
+                       runtime_printhex(va_arg(va, uint64));
+                       break;
+               }
+               lp = p+1;
+       }
+       if(p > lp)
+               gwrite(lp, p-lp);
+
+       //runtime_unlock(&debuglock);
+}
+
+void
+runtime_printpc(void *p __attribute__ ((unused)))
+{
+       runtime_prints("PC=");
+       runtime_printhex((uint64)runtime_getcallerpc(p));
+}
+
+void
+runtime_printbool(_Bool v)
+{
+       if(v) {
+               gwrite("true", 4);
+               return;
+       }
+       gwrite("false", 5);
+}
+
+void
+runtime_printfloat(double v)
+{
+       byte buf[20];
+       int32 e, s, i, n;
+       float64 h;
+
+       if(runtime_isNaN(v)) {
+               gwrite("NaN", 3);
+               return;
+       }
+       if(runtime_isInf(v, 1)) {
+               gwrite("+Inf", 4);
+               return;
+       }
+       if(runtime_isInf(v, -1)) {
+               gwrite("-Inf", 4);
+               return;
+       }
+
+       n = 7;  // digits printed
+       e = 0;  // exp
+       s = 0;  // sign
+       if(v != 0) {
+               // sign
+               if(v < 0) {
+                       v = -v;
+                       s = 1;
+               }
+
+               // normalize
+               while(v >= 10) {
+                       e++;
+                       v /= 10;
+               }
+               while(v < 1) {
+                       e--;
+                       v *= 10;
+               }
+
+               // round
+               h = 5;
+               for(i=0; i<n; i++)
+                       h /= 10;
+
+               v += h;
+               if(v >= 10) {
+                       e++;
+                       v /= 10;
+               }
+       }
+
+       // format +d.dddd+edd
+       buf[0] = '+';
+       if(s)
+               buf[0] = '-';
+       for(i=0; i<n; i++) {
+               s = v;
+               buf[i+2] = s+'0';
+               v -= s;
+               v *= 10.;
+       }
+       buf[1] = buf[2];
+       buf[2] = '.';
+
+       buf[n+2] = 'e';
+       buf[n+3] = '+';
+       if(e < 0) {
+               e = -e;
+               buf[n+3] = '-';
+       }
+
+       buf[n+4] = (e/100) + '0';
+       buf[n+5] = (e/10)%10 + '0';
+       buf[n+6] = (e%10) + '0';
+       gwrite(buf, n+7);
+}
+
+void
+runtime_printcomplex(__complex double v)
+{
+       gwrite("(", 1);
+       runtime_printfloat(__builtin_creal(v));
+       runtime_printfloat(__builtin_cimag(v));
+       gwrite("i)", 2);
+}
+
+void
+runtime_printuint(uint64 v)
+{
+       byte buf[100];
+       int32 i;
+
+       for(i=nelem(buf)-1; i>0; i--) {
+               buf[i] = v%10 + '0';
+               if(v < 10)
+                       break;
+               v = v/10;
+       }
+       gwrite(buf+i, nelem(buf)-i);
+}
+
+void
+runtime_printint(int64 v)
+{
+       if(v < 0) {
+               gwrite("-", 1);
+               v = -v;
+       }
+       runtime_printuint(v);
+}
+
+void
+runtime_printhex(uint64 v)
+{
+       static const char *dig = "0123456789abcdef";
+       byte buf[100];
+       int32 i;
+
+       i=nelem(buf);
+       for(; v>0; v/=16)
+               buf[--i] = dig[v%16];
+       if(i == nelem(buf))
+               buf[--i] = '0';
+       buf[--i] = 'x';
+       buf[--i] = '0';
+       gwrite(buf+i, nelem(buf)-i);
+}
+
+void
+runtime_printpointer(void *p)
+{
+       runtime_printhex((uint64)(uintptr)p);
+}
+
+void
+runtime_printstring(String v)
+{
+       // extern uint32 runtime_maxstring;
+
+       // if(v.len > runtime_maxstring) {
+       //      gwrite("[invalid string]", 16);
+       //      return;
+       // }
+       if(v.__length > 0)
+               gwrite(v.__data, v.__length);
+}
+
+void
+__go_print_space(void)
+{
+       gwrite(" ", 1);
+}
+
+void
+__go_print_nl(void)
+{
+       gwrite("\n", 1);
+}