|
|
1.1 root 1: static char sccsid[] = "@(#)format.c 2.12";
2:
3: #include <ctype.h>
4: #include "macdefs.h"
5: #include "cdb.h"
6:
7: export int vcNest; /* nesting level for printg structures and unions */
8: export char vsbFmt[20]; /* format spec for addresses */
9: static char vsbAdr[20]; /* where we stick last address formatted - SbFAdr */
10:
11: char *vmpBtSb[] = { /* map basic types into the type names */
12: "undefined",
13: "Function Argument",
14: "char",
15: "short",
16: "int",
17: "long",
18: "float",
19: "double",
20: "struct",
21: "union",
22: "enum",
23: "member of enum",
24: "unsigned char",
25: "unsigned short",
26: "unsigned int",
27: "unsigned long"
28: };
29:
30:
31: /* S B F A D R */
32:
33: export char * SbFAdr(adrLong, fMask)
34: long adrLong;
35: FLAGT fMask;
36: {
37: if (vsbFmt[0] == chNull)
38: strcpy(vsbFmt, "%lx");
39: #if (CBINT == CBSHORT)
40: if (fMask)
41: adrLong &= 0x0000ffffL;
42: #endif
43: sprintf(vsbAdr, vsbFmt, adrLong);
44: return(vsbAdr);
45: } /* SbFAdr */
46:
47:
48: /* D F F T Y */
49:
50: export DFE DfFTy(ty, fAlternate)
51: pTYR ty;
52: FLAGT fAlternate;
53: {
54: int tq;
55:
56: tq = TqFTy(ty, 1);
57: if ((tq == tqPtr) OR (tq == tqArray)) {
58: if ( fAlternate
59: AND (ty->td.bt == btChar)
60: AND ((tq == tqArray AND TqFTy(ty, 2) == tqNil)
61: OR (ty->td.tq1 == tqPtr)) ) {
62: return((tq == tqPtr) ? dfPStr : dfStr); /* so it looks pretty */
63: } /* if */
64: return(dfAddr); /* use address display mode */
65: } /* if */
66:
67: if (ty->td.st == stReg)
68: return(dfAddr); /* a hackers delight */
69:
70: switch (ty->td.bt) {
71: case btNil:
72: return(dfNil);
73: case btUnion:
74: case btStruct:
75: if (fAlternate)
76: #ifdef BSD42
77: return(dfStruct);
78: #else
79: return(dfAddr);
80: #endif
81: else
82: return(dfAddr);
83: case btUChar:
84: case btUInt:
85: case btULong:
86: return(dfUnsigned);
87: case btShort:
88: case btInt:
89: case btLong:
90: return(dfDecimal);
91: case btFloat:
92: case btDouble:
93: return(dfGFloat);
94: case btEType:
95: return(dfEnum);
96: case btChar:
97: if (tq == tqArray AND fAlternate)
98: return(dfStr);
99: else
100: return(dfChar);
101: } /* switch */
102: return(dfDecimal);
103: } /* DfFTy */
104:
105:
106: /* C B F C H */
107:
108: export int CbFCh(ch)
109: char ch;
110: {
111: switch (ch) {
112: case 'b':
113: case 'c':
114: return(1);
115: case 'e':
116: case 'f':
117: case 'g':
118: return(CBFLOAT);
119: case 'E':
120: case 'F':
121: case 'G':
122: return(CBDOUBLE);
123: case 'D':
124: case 'O':
125: case 'U':
126: case 'X':
127: return(CBLONG);
128: case 'd':
129: case 'o':
130: case 'u':
131: case 'x':
132: case 'a':
133: case 'n':
134: case 'p':
135: case 's':
136: case 'B':
137: case 'C':
138: case 'S':
139: return(-1); /* says to use `current' size */
140: } /* switch */
141: return(-1);
142: } /* CbFCh */
143:
144:
145: /* D F F C H */
146:
147: export DFE DfFCh(ch)
148: char ch;
149: {
150: switch (ch) {
151: case 'a':
152: return(dfStr);
153: case 'C':
154: case 'c':
155: return(dfChar);
156: case 'b':
157: case 'D':
158: case 'd':
159: return(dfDecimal);
160: case 'E':
161: case 'e':
162: return(dfEFloat);
163: case 'F':
164: case 'f':
165: return(dfFFloat);
166: case 'G':
167: case 'g':
168: return(dfGFloat);
169: case 'n':
170: return(dfNil);
171: case 'O':
172: case 'o':
173: return(dfOctal);
174: case 'p':
175: return(dfProc);
176: case 'S':
177: return(dfStruct);
178: case 's':
179: return(dfPStr);
180: case 'U':
181: case 'u':
182: return(dfUnsigned);
183: case 't':
184: return(dfType);
185: case 'X':
186: case 'x':
187: return(dfHex);
188: } /* switch */
189: return(dfNil);
190: } /* DfFCh */
191:
192:
193: /* G E T M O D E */
194:
195: export void GetMode(mode)
196: pMODER mode;
197: {
198: char ch;
199: TKE tk;
200:
201: /* consider the next few tokens as variable formatting info */
202: /* NOTE: we assume WE get next token!! */
203: tk = TkNext();
204: mode->imap = 0;
205: if (tk == tkStar) {
206: mode->imap = 1;
207: tk = TkNext();
208: } /* if */
209: if (tk == tkNil) {
210: return;
211: }
212: else if (tk == tkNumber) {
213: mode->cnt = atoi(vsbTok);
214: tk = TkNext();
215: }
216: else {
217: mode->cnt = 1;
218: } /* if */
219:
220: if (tk == tkStr) {
221: ch = vsbTok[0];
222: /* determine # of bytes based on format */
223: mode->len = CbFCh(ch);
224: mode->df = DfFCh(ch);
225: if (vsbTok[1] != chNull)
226: mode->len = (vsbTok[1] == 'b') ? 1 :
227: (vsbTok[1] == 's') ? 2 :
228: (vsbTok[1] == 'l') ? 4 : atoi(&vsbTok[1]);
229: tk = TkNext();
230: } /* if */
231: } /* GetMode */
232:
233:
234: /* I N C F T Y M O D E */
235:
236: export int IncFTyMode(ty, mode)
237: pTYR ty;
238: pMODER mode;
239: {
240: int i;
241:
242: if ((ty->td.st == stSpc) /* we do NOT allow inc's of specials */
243: OR (mode->df == dfType))
244: return(0);
245:
246: #ifdef BSD41
247: ty->sbVar = -1; /* because this name is no longer correct */
248: #else
249: ty->sbVar[0] = chNull; /* because this name is no longer correct */
250: #endif
251: if (ty->td.st == stReg) {
252: return(1);
253: }
254: else {
255: if (mode->df == dfStr) {
256: if (mode->len < 0) {
257: i = -mode->len;
258: mode->len = -1;
259: return(i);
260: }
261: else {
262: return(mode->cnt * mode->len);
263: } /* if */
264: }
265: else if (mode->df == dfPStr) {
266: return(mode->cnt * CBPOINT);
267: }
268: else {
269: return(mode->cnt * mode->len);
270: } /* if */
271: } /* if */
272: } /* IncFTyMode */
273:
274:
275: /* D I S P V A L */
276:
277: export void DispVal(adrLong, tyIn, mode, fShowAdr, fIndirect, fAlternate)
278: long adrLong;
279: pTYR tyIn;
280: pMODER mode;
281: FLAGT fShowAdr, fIndirect, fAlternate;
282: {
283: int modval, width, cPrint, cb;
284: int len, cnt, i;
285: FLAGT fConstant, fCheckNull, fRandomLength;
286: char ch, *sbVar;
287: long mask, val, *pKludge;
288: double valDouble;
289: DFE df;
290: STUFFU stuff;
291: MODER amodeTemp;
292: ADRT adrWorking;
293: #if (CBINT == CBSHORT)
294: short valMasked;
295: #else
296: long valMasked;
297: #endif
298:
299: modval = 1;
300: /* if the mode is supplied, we ignore the TY, else we use it to build
301: * a plausible display format.
302: */
303: if (mode == modeNil) {
304: mode = &amodeTemp;
305: cnt = 1;
306: df = dfNil;
307: }
308: else {
309: df = mode->df;
310: cnt = mode->cnt;
311: len = mode->len;
312: /* this may not be right, but we need to force the size of what we
313: * are looking at to be the size we requested in the format.
314: * this way, when we say `sbWord/c;<cr>;<cr>;.='H' ' we actually
315: * do the `correct' character assignment.
316: */
317: if (len > 0) {
318: switch (len) {
319: case 1:
320: CopyTy(tyIn, vtyChar);
321: if (df == dfUnsigned)
322: tyIn->td.bt = btUChar;
323: break;
324: case 2:
325: CopyTy(tyIn, vtyShort);
326: if (df == dfUnsigned)
327: tyIn->td.bt = btUShort;
328: break;
329: case 4:
330: CopyTy(tyIn, vtyLong);
331: if (df == dfUnsigned)
332: tyIn->td.bt = btULong;
333: break;
334: } /* switch */
335: } /* if */
336: } /* if */
337:
338: if (df == dfNil) {
339: /* they did not specify display format */
340: df = DfFTy(tyIn, fAlternate);
341: len = (df == dfStr OR df == dfPStr) ? -1 : CbFTy(tyIn);
342: /* remember this stuff */
343: mode->df = df;
344: mode->cnt = cnt;
345: mode->len = len;
346: } /* if */
347: fRandomLength = (len == -1);
348: if ((len == -1)
349: AND (df != dfStr)
350: AND (df != dfPStr))
351: mode->len = len = CbFTy(tyIn);
352:
353: #ifdef ONYX
354: /* we may want to do this for other than ONYX, too. */
355: if (FOdd(adrLong))
356: cb = 1; /* we assume it is actually a single byte */
357: #endif
358: cb = len;
359: mask = -1;
360: if (df == dfPStr) {
361: cb = CBPOINT;
362: }
363: else if (df == dfStr) {
364: cb = CBCHAR;
365: if (fRandomLength)
366: mode->len = 0; /* we will stuff final count in here for Inc */
367: }
368: else if (df == dfProc) {
369: fShowAdr = false;
370: fIndirect = false;
371: }
372: else {
373: /* here we try to skull out a good width for this size */
374: width = 7;
375: modval = 8;
376: if (len == 1)
377: mask = 0x00ff;
378: else if (len == 2)
379: mask = 0xffff;
380: else if (len == 4) {
381: mask = 0xffffffff;
382: width = 12;
383: modval = 4;
384: } /* if */
385: } /* if */
386:
387: if (cnt == 1)
388: width = 0; /* we don't try to add anything if there's just one */
389:
390: if (df == dfType) {
391: fIndirect = false;
392: fShowAdr = false;
393: } /* if */
394: cPrint = 0;
395: while (cnt--) {
396: vimap = mode->imap; /* sorta kludgey - sorry */
397: /*
398: fConstant = tyIn->td.fConstant;
399: tyIn->td.fConstant = false;
400: */
401: val = (fIndirect) ? ValFAdr(adrLong, tyIn) : adrLong;
402: /*
403: tyIn->td.fConstant = fConstant;
404: */
405: vimap = 0;
406: valMasked = val & mask;
407: if (cb < 4)
408: val = valMasked;
409: adrWorking = adrLong;
410: if (fShowAdr
411: AND fIndirect
412: AND (!tyIn->td.fConstant)
413: AND (cPrint % modval == 0)) {
414: if ((cPrint == 0)
415: AND (tyIn != tyNil)
416: AND (*(sbVar = SbInCore(tyIn[0].sbVar)) != chNull)
417: AND (*sbVar != '*'))
418: #ifdef BSD41
419: printf("%s = ", sbVar);
420: #else
421: printf("%.8s = ", sbVar);
422: #endif
423: else
424: printf("%s ", SbFAdr(adrLong, true));
425: } /* if */
426: switch (df) {
427: case dfType:
428: PxTy(tyIn);
429: break;
430: case dfAddr:
431: printf("%*s", width, SbFAdr(val, true));
432: break;
433: case dfDecimal:
434: printf("%*ld", width, val);
435: break;
436: case dfUnsigned:
437: val &= mask;
438: printf("%*lu", width, val);
439: break;
440: case dfOctal:
441: val &= mask;
442: printf("%*lo", width, val);
443: break;
444: case dfHex:
445: val &= mask;
446: printf("%*lx", width, val);
447: break;
448: case dfChar:
449: if (valMasked < ' ')
450: printf("^%c (%o)", valMasked+0100, valMasked);
451: else printf("%c", valMasked);
452: break;
453: case dfFFloat:
454: case dfEFloat:
455: case dfGFloat:
456: /* the following tries to get the right
457: * conversions to happen.
458: */
459: if (cb == 4) {
460: stuff.lng = val;
461: valDouble = stuff.fl;
462: }
463: else { /* we assume double */
464: pKludge = (long *)&valDouble;
465: pKludge[0] = val;
466: pKludge[1] = ValFAdr(adrLong+4, vtyLong);
467: } /* if */
468: if (df == dfFFloat)
469: printf("%f", valDouble);
470: else if (df == dfEFloat)
471: printf("%e", valDouble);
472: else
473: printf("%g", valDouble);
474: break;
475: case dfEnum:
476: PxEnum(val, tyIn);
477: break;
478: case dfStruct:
479: IssFPxStruct(adrWorking, tyIn, true);
480: break;
481: case dfProc:
482: PrintPos(valMasked, fmtFile+fmtProc+fmtLn+fmtPrint+fmtSave);
483: break;
484: case dfPStr:
485: adrWorking = valMasked; /* and fall through */
486: case dfStr:
487: fCheckNull = false;
488: if (fRandomLength) {
489: if (adrWorking == 0) {
490: printf("<null pointer>");
491: break;
492: } /* if */
493: len = 128;
494: fCheckNull = true;
495: } /* if */
496: printf("\"");
497: for (i=0; i != len; i++) {
498: ch = GetByte((ADRT)(adrWorking+i), spaceData);
499: if ((ch == chNull) AND fCheckNull)
500: break;
501: if (ch < ' ')
502: printf("^%c", ch+0100);
503: else printf("%c", ch);
504: } /* for */
505: printf("\"");
506: break;
507: } /* switch */
508:
509: if (fRandomLength) {
510: i += 1; /* if we did /s or /a, this moves us past the chNull */
511: if (df == dfStr)
512: mode->len -= i; /* remember size for IncFTyMode */
513: } /* if */
514:
515: /* advance */
516: if (cnt) {
517: #ifdef BSD41
518: tyIn->sbVar = -1; /* because this name is no longer correct */
519: #else
520: tyIn->sbVar[0] = chNull;/* because this name is no longer correct */
521: #endif
522:
523: adrLong += (df == dfStr) ? i : CbFTy(tyIn);
524: if (((++cPrint % modval) == 0)
525: OR (df == dfPStr OR df == dfStr OR df == dfStruct)) {
526: printf("\n");
527: } /* if */
528: } /* if */
529: } /* while */
530: } /* DispVal */
531:
532:
533: /* P X E N U M */
534:
535: export void PxEnum(val, ty)
536: long val;
537: pTYR ty;
538: {
539: #ifndef BSD42
540: printf("%ld", val);
541: #else
542: int i;
543: char *sb, *sbName, *sbType, sbLook[10];
544: pXTYR xty;
545:
546: xty = (pXTYR) (ty + 1);
547: sbType = SbInCore(xty->issRef);
548: sbName = SbInCore(SbSafe(sbType));
549: sprintf(sbLook, ":%d,", val); /* value we are looking for */
550: i = IFSbSb(sbType, sbLook);
551: if (i == -1) {
552: printf("Value %d is not defined for 'enum %s'", val, sbName);
553: return;
554: }
555: sb = sbType + i - 1;
556: /* got it - now back up to before the name */
557: while ((*sb != ',') AND (*sb != '='))
558: sb--;
559: if (*sb == '=')
560: sb++; /* point past 'e' */
561: sb++; /* past the ',' or the '=' */
562: printf("%s", SbInCore(SbSafe(sb)));
563: #endif
564: } /* PxEnum */
565:
566:
567: /* I S S F P X S T R U C T */
568:
569: export long IssFPxStruct(adr, tyStruct, fDoVal)
570: ADRT adr;
571: pTYR tyStruct;
572: FLAGT fDoVal;
573: {
574: #ifndef BSD42
575: UError("There is insufficient information to do a structure dump");
576: #else
577: int i;
578: long adrLong, iss;
579: char chType, *sb, *sbName, *sbEqual, *sbType, sbLook[10];
580: char sbStart[1000]; /* where we stash the type info */
581: FLAGT fDidit;
582: TYR tyField[cTyMax], tyT[cTyMax];
583: pXTYR xty;
584:
585: xty = (pXTYR) (tyStruct + 1);
586: if (xty->st != stExtend) {
587: adrLong = adr;
588: printf("%s", SbFAdr(adrLong));
589: return(-1);
590: }
591: iss = xty->issRef;
592: strcpy(sbStart, SbInCore(iss));
593: sbType = sbStart;
594: sbName = SbInCore(SbSafe(sbType));
595: i = IFSbSb(sbType, "=");
596: sbType += i + 1;
597: if ((i == -1)
598: OR ((*sbType != 's') AND (*sbType != 'u')) )
599: UError("This does not appear to be a stuct or union");
600: chType = *sbType++;
601: while (isdigit(*sbType)) /* get past size value */
602: sbType++;
603: printf("%s %s {\n", (chType == 's') ? "struct" : "union", sbName);
604: vcNest++; /* kick nesting level for indent printing */
605: while (*sbType) {
606: sbName = SbInCore(SbSafe(sbType));
607: #ifdef BSD41
608: tyField[0].sbVar = bitHigh | (long)sbName;
609: #else
610: strncpy(tyField[0].sbVar, sbName, cbVarMax);
611: #endif
612: tyField[0].td.st = stStruct;
613: adrLong = adr;
614: adrLong = AdrFField(adrLong, tyStruct, tyField);
615: sbEqual = strchr(sbType, '=');
616: sb = sbType; /* remember where we are in case of imbeded struct */
617: sbType = strchr(sbType, ';') + 1;
618: fDidit = false;
619: if ((sbEqual != sbNil) AND (sbEqual < sbType)) {
620: if (*++sbEqual == 'a') {
621: /* this should get us through the array declaration */
622: sbType = strchr(sbEqual, ';') + 1;
623: sbType = strchr(sbType, ';') + 1;
624: sbType = strchr(sbType, ';') + 1;
625: sbType = strchr(sbType, ';') + 1; /* this should be next name */
626: }
627: else if (*sbEqual == 's') {
628: /* we have a struct, recurse */
629: xty = (pXTYR) (tyField + 1);
630: xty->issRef = iss + (sb - sbStart);
631: for (i=0; i<vcNest; i++)
632: printf(" ");
633: iss = IssFPxStruct(adrLong, tyField, fDoVal);
634: printf("\n");
635: strcpy(sbStart, SbInCore(iss));
636: sbType = sbStart;
637: sbType = strchr(sbType, ';') + 1; /* this should be next name */
638: fDidit = true;
639: }
640: }
641: if (!fDidit) {
642: for (i=0; i<vcNest; i++)
643: printf(" ");
644: if (fDoVal)
645: DispVal(adrLong, tyField, modeNil, true, true, true);
646: else
647: PxTy(tyField);
648: printf(";\n");
649: }
650: if (*sbType == ';')
651: break; /* end of the line */
652: } /* while */
653: for (i=0; i<vcNest; i++)
654: printf(" ");
655: vcNest--;
656: printf("};");
657: return(iss+sbType-sbStart+1); /* points 1 past ending ';;' */
658: #endif
659: } /* IssFPxStruct */
660:
661:
662: /* P X T Y */
663:
664: export void PxTy(ty)
665: pTYR ty;
666: {
667: int ipd, i, j, tq, tqLast, st, bt;
668: short *rgDim;
669: FLAGT fDidName, fHaveExtension, fNeedRP;
670: pXTYR xty;
671:
672: tqLast = tqNil;
673: fDidName = false;
674: st = ty->td.st;
675: bt = ty->td.bt;
676: xty = (pXTYR)(ty+1);
677: fHaveExtension = (xty->st == stExtend);
678: rgDim = xty->rgDim;
679:
680: #ifdef BSD41
681: if (ty->td.st == stProc) {
682: /* BSD 4.1 does not know return type for procedures */
683: ipd = IpdFName(SbInCore(ty->sbVar));
684: DispFrame(adrNil,ipd, adrNil, adrNil, -1, false, false);
685: return;
686: }
687: #ifdef BSD42
688: tq = TqFTy(ty, 1);
689: if ((tq == tqNil)
690: AND ((bt == btStruct)
691: OR (bt == btUnion))) {
692: IssFPxStruct(0L, ty, false);
693: fDidName = true;
694: }
695: else {
696: /* print type name */
697: printf("%s ", vmpBtSb[bt]);
698: if ((bt == btEType)
699: OR (bt == btStruct)
700: OR (bt == btUnion)) {
701: printf("%s ",SbInSafe(xty->issRef));
702: }
703: }
704: #else
705: /* print type name */
706: printf("%s ", vmpBtSb[bt]);
707: #endif
708: #else
709: /* print type name */
710: printf("%s ", vmpBtSb[bt]);
711: #endif
712: fNeedRP = false;
713: tqLast = tqNil;
714: for (i=1; i<=6; i++) {
715: if ((tq = TqFTy(ty, i)) == tqNil)
716: break;
717: if ((tqLast != tqNil)
718: AND (tq != tqLast)) {
719: printf("(");
720: fNeedRP = true;
721: } /* if */
722: switch (tq) {
723: case tqPtr:
724: printf("*");
725: break;
726: case tqFunc:
727: ipd = IpdFName(SbInCore(ty->sbVar));
728: DispFrame(adrNil,ipd, adrNil, adrNil, -1, false, false);
729: fDidName = true; /* printed by DispFrame */
730: return;
731: case tqArray:
732: if (!fDidName) {
733: printf("%s", SbInCore(ty->sbVar));
734: fDidName = true;
735: } /* if */
736: if (fHaveExtension) {
737: for (j=0; (j < 2) AND (rgDim[j] != 0); j++) {
738: if (rgDim[j] < 0)
739: printf("[]");
740: else
741: printf("[%d]", rgDim[j]+1);
742: }
743: }
744: else {
745: printf("[]");
746: }
747: break;
748: } /* switch */
749: if (fNeedRP) {
750: fNeedRP = false;
751: printf(")");
752: }
753: tqLast = tq;
754: } /* for */
755: if (!fDidName)
756: printf("%s", SbInCore(ty->sbVar));
757: if (ty->td.width != 0)
758: printf(" : %d", ty->td.width);
759: } /* PxTy */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.