github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/8c/list.c (about)

     1  // Inferno utils/8c/list.c
     2  // http://code.google.com/p/inferno-os/source/browse/utils/8c/list.c
     3  //
     4  //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
     5  //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
     6  //	Portions Copyright © 1997-1999 Vita Nuova Limited
     7  //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
     8  //	Portions Copyright © 2004,2006 Bruce Ellis
     9  //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    10  //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    11  //	Portions Copyright © 2009 The Go Authors.  All rights reserved.
    12  //
    13  // Permission is hereby granted, free of charge, to any person obtaining a copy
    14  // of this software and associated documentation files (the "Software"), to deal
    15  // in the Software without restriction, including without limitation the rights
    16  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    17  // copies of the Software, and to permit persons to whom the Software is
    18  // furnished to do so, subject to the following conditions:
    19  //
    20  // The above copyright notice and this permission notice shall be included in
    21  // all copies or substantial portions of the Software.
    22  //
    23  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    24  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    25  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    26  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    27  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    28  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    29  // THE SOFTWARE.
    30  
    31  #define EXTERN
    32  #include "gc.h"
    33  
    34  void
    35  listinit(void)
    36  {
    37  
    38  	fmtinstall('A', Aconv);
    39  	fmtinstall('B', Bconv);
    40  	fmtinstall('P', Pconv);
    41  	fmtinstall('S', Sconv);
    42  	fmtinstall('D', Dconv);
    43  	fmtinstall('R', Rconv);
    44  }
    45  
    46  int
    47  Bconv(Fmt *fp)
    48  {
    49  	char str[STRINGSZ], ss[STRINGSZ], *s;
    50  	Bits bits;
    51  	int i;
    52  
    53  	str[0] = 0;
    54  	bits = va_arg(fp->args, Bits);
    55  	while(bany(&bits)) {
    56  		i = bnum(bits);
    57  		if(str[0])
    58  			strcat(str, " ");
    59  		if(var[i].sym == S) {
    60  			sprint(ss, "$%d", var[i].offset);
    61  			s = ss;
    62  		} else
    63  			s = var[i].sym->name;
    64  		if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
    65  			break;
    66  		strcat(str, s);
    67  		bits.b[i/32] &= ~(1L << (i%32));
    68  	}
    69  	return fmtstrcpy(fp, str);
    70  }
    71  
    72  int
    73  Pconv(Fmt *fp)
    74  {
    75  	char str[STRINGSZ];
    76  	Prog *p;
    77  
    78  	p = va_arg(fp->args, Prog*);
    79  	switch(p->as) {
    80  	case ADATA:
    81  		sprint(str, "(%L)	%A	%D/%d,%D",
    82  			p->lineno, p->as, &p->from, p->from.scale, &p->to);
    83  		break;
    84  
    85  	case ATEXT:
    86  		if(p->from.scale) {
    87  			sprint(str, "(%L)	%A	%D,%d,%lD",
    88  				p->lineno, p->as, &p->from, p->from.scale, &p->to);
    89  			break;
    90  		}
    91  		sprint(str, "(%L)	%A	%D,%lD",
    92  			p->lineno, p->as, &p->from, &p->to);
    93  		break;
    94  
    95  	default:
    96  		sprint(str, "(%L)	%A	%D,%D",
    97  			p->lineno, p->as, &p->from, &p->to);
    98  		break;
    99  	}
   100  	return fmtstrcpy(fp, str);
   101  }
   102  
   103  int
   104  Aconv(Fmt *fp)
   105  {
   106  	int i;
   107  
   108  	i = va_arg(fp->args, int);
   109  	return fmtstrcpy(fp, anames[i]);
   110  }
   111  
   112  int
   113  Dconv(Fmt *fp)
   114  {
   115  	char str[STRINGSZ], s[STRINGSZ];
   116  	Adr *a;
   117  	int i;
   118  
   119  	a = va_arg(fp->args, Adr*);
   120  	i = a->type;
   121  
   122  	if(fp->flags & FmtLong) {
   123  		if(i == D_CONST2)
   124  			sprint(str, "$%d-%d", a->offset, a->offset2);
   125  		else {
   126  			// ATEXT dst is not constant
   127  			sprint(str, "!!%D", a);
   128  		}
   129  		goto brk;
   130  	}
   131  
   132  	if(i >= D_INDIR) {
   133  		if(a->offset)
   134  			sprint(str, "%d(%R)", a->offset, i-D_INDIR);
   135  		else
   136  			sprint(str, "(%R)", i-D_INDIR);
   137  		goto brk;
   138  	}
   139  	switch(i) {
   140  	default:
   141  		if(a->offset)
   142  			sprint(str, "$%d,%R", a->offset, i);
   143  		else
   144  			sprint(str, "%R", i);
   145  		break;
   146  
   147  	case D_NONE:
   148  		str[0] = 0;
   149  		break;
   150  
   151  	case D_BRANCH:
   152  		sprint(str, "%d", a->offset);
   153  		break;
   154  
   155  	case D_EXTERN:
   156  		sprint(str, "%s+%d(SB)", a->sym->name, a->offset);
   157  		break;
   158  
   159  	case D_STATIC:
   160  		sprint(str, "%s<>+%d(SB)", a->sym->name, a->offset);
   161  		break;
   162  
   163  	case D_AUTO:
   164  		if(a->sym)
   165  			sprint(str, "%s+%d(SP)", a->sym->name, a->offset);
   166  		else
   167  			sprint(str, "%d(SP)", a->offset);
   168  		break;
   169  
   170  	case D_PARAM:
   171  		if(a->sym)
   172  			sprint(str, "%s+%d(FP)", a->sym->name, a->offset);
   173  		else
   174  			sprint(str, "%d(FP)", a->offset);
   175  		break;
   176  
   177  	case D_CONST:
   178  		sprint(str, "$%d", a->offset);
   179  		break;
   180  
   181  	case D_CONST2:
   182  		if(!(fp->flags & FmtLong)) {
   183  			// D_CONST2 outside of ATEXT should not happen
   184  			sprint(str, "!!$%d-%d", a->offset, a->offset2);
   185  		}
   186  		break;
   187  
   188  	case D_FCONST:
   189  		sprint(str, "$(%.17e)", a->dval);
   190  		break;
   191  
   192  	case D_SCONST:
   193  		sprint(str, "$\"%S\"", a->sval);
   194  		break;
   195  
   196  	case D_ADDR:
   197  		a->type = a->index;
   198  		a->index = D_NONE;
   199  		sprint(str, "$%D", a);
   200  		a->index = a->type;
   201  		a->type = D_ADDR;
   202  		goto conv;
   203  	}
   204  brk:
   205  	if(a->index != D_NONE) {
   206  		sprint(s, "(%R*%d)", (int)a->index, (int)a->scale);
   207  		strcat(str, s);
   208  	}
   209  conv:
   210  	return fmtstrcpy(fp, str);
   211  }
   212  
   213  char*	regstr[] =
   214  {
   215  	"AL",	/* [D_AL] */
   216  	"CL",
   217  	"DL",
   218  	"BL",
   219  	"AH",
   220  	"CH",
   221  	"DH",
   222  	"BH",
   223  
   224  	"AX",	/* [D_AX] */
   225  	"CX",
   226  	"DX",
   227  	"BX",
   228  	"SP",
   229  	"BP",
   230  	"SI",
   231  	"DI",
   232  
   233  	"F0",	/* [D_F0] */
   234  	"F1",
   235  	"F2",
   236  	"F3",
   237  	"F4",
   238  	"F5",
   239  	"F6",
   240  	"F7",
   241  
   242  	"CS",	/* [D_CS] */
   243  	"SS",
   244  	"DS",
   245  	"ES",
   246  	"FS",
   247  	"GS",
   248  
   249  	"GDTR",	/* [D_GDTR] */
   250  	"IDTR",	/* [D_IDTR] */
   251  	"LDTR",	/* [D_LDTR] */
   252  	"MSW",	/* [D_MSW] */
   253  	"TASK",	/* [D_TASK] */
   254  
   255  	"CR0",	/* [D_CR] */
   256  	"CR1",
   257  	"CR2",
   258  	"CR3",
   259  	"CR4",
   260  	"CR5",
   261  	"CR6",
   262  	"CR7",
   263  
   264  	"DR0",	/* [D_DR] */
   265  	"DR1",
   266  	"DR2",
   267  	"DR3",
   268  	"DR4",
   269  	"DR5",
   270  	"DR6",
   271  	"DR7",
   272  
   273  	"TR0",	/* [D_TR] */
   274  	"TR1",
   275  	"TR2",
   276  	"TR3",
   277  	"TR4",
   278  	"TR5",
   279  	"TR6",
   280  	"TR7",
   281  
   282  	"X0",	/* [D_X0] */
   283  	"X1",
   284  	"X2",
   285  	"X3",
   286  	"X4",
   287  	"X5",
   288  	"X6",
   289  	"X7",
   290  
   291  	"NONE",	/* [D_NONE] */
   292  };
   293  
   294  int
   295  Rconv(Fmt *fp)
   296  {
   297  	char str[STRINGSZ];
   298  	int r;
   299  
   300  	r = va_arg(fp->args, int);
   301  	if(r >= D_AL && r <= D_NONE)
   302  		sprint(str, "%s", regstr[r-D_AL]);
   303  	else
   304  		sprint(str, "gok(%d)", r);
   305  
   306  	return fmtstrcpy(fp, str);
   307  }
   308  
   309  int
   310  Sconv(Fmt *fp)
   311  {
   312  	int i, c;
   313  	char str[STRINGSZ], *p, *a;
   314  
   315  	a = va_arg(fp->args, char*);
   316  	p = str;
   317  	for(i=0; i<sizeof(double); i++) {
   318  		c = a[i] & 0xff;
   319  		if(c >= 'a' && c <= 'z' ||
   320  		   c >= 'A' && c <= 'Z' ||
   321  		   c >= '0' && c <= '9') {
   322  			*p++ = c;
   323  			continue;
   324  		}
   325  		*p++ = '\\';
   326  		switch(c) {
   327  		default:
   328  			if(c < 040 || c >= 0177)
   329  				break;	/* not portable */
   330  			p[-1] = c;
   331  			continue;
   332  		case 0:
   333  			*p++ = 'z';
   334  			continue;
   335  		case '\\':
   336  		case '"':
   337  			*p++ = c;
   338  			continue;
   339  		case '\n':
   340  			*p++ = 'n';
   341  			continue;
   342  		case '\t':
   343  			*p++ = 't';
   344  			continue;
   345  		}
   346  		*p++ = (c>>6) + '0';
   347  		*p++ = ((c>>3) & 7) + '0';
   348  		*p++ = (c & 7) + '0';
   349  	}
   350  	*p = 0;
   351  	return fmtstrcpy(fp, str);
   352  }