|
|
1.1 root 1: /* Code for handling XREF output from GNU C++. 1.1.1.4 root 2: Copyright (C) 1992, 1993 Free Software Foundation, Inc. 1.1 root 3: Contributed by Michael Tiemann ([email protected]) 4: 5: This file is part of GNU CC. 6: 7: GNU CC is free software; you can redistribute it and/or modify 8: it under the terms of the GNU General Public License as published by 9: the Free Software Foundation; either version 2, or (at your option) 10: any later version. 11: 12: GNU CC is distributed in the hope that it will be useful, 13: but WITHOUT ANY WARRANTY; without even the implied warranty of 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15: GNU General Public License for more details. 16: 17: You should have received a copy of the GNU General Public License 18: along with GNU CC; see the file COPYING. If not, write to 19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 20: 21: 22: #include "config.h" 23: #include "tree.h" 24: #include <stdio.h> 25: #include "cp-tree.h" 26: #include "input.h" 27: 28: #include <ctype.h> 29: 1.1.1.4 root 30: extern char *getpwd (); 1.1.1.2 root 31: 1.1.1.3 root 32: extern char *index (); 33: extern char *rindex (); 34: 1.1 root 35: /* The character(s) used to join a directory specification (obtained with 36: getwd or equivalent) with a non-absolute file name. */ 37: 38: #ifndef FILE_NAME_JOINER 39: #define FILE_NAME_JOINER "/" 40: #endif 41: 42: /* Nonzero if NAME as a file name is absolute. */ 43: #ifndef FILE_NAME_ABSOLUTE_P 44: #define FILE_NAME_ABSOLUTE_P(NAME) (NAME[0] == '/') 45: #endif 46: 47: /* For cross referencing. */ 48: 49: int flag_gnu_xref; 50: 51: /************************************************************************/ 52: /* */ 53: /* Common definitions */ 54: /* */ 55: /************************************************************************/ 56: 57: #ifndef TRUE 58: #define TRUE 1 59: #endif 60: #ifndef FALSE 61: #define FALSE 0 62: #endif 63: #ifndef NULL 64: #define NULL 0 65: #endif 66: 67: #define PALLOC(typ) ((typ *) calloc(1,sizeof(typ))) 68: 69: 1.1.1.2 root 70: /* Return a malloc'd copy of STR. */ 71: #define SALLOC(str) \ 1.1.1.4 root 72: ((char *) ((str) == NULL ? NULL \ 73: : (char *) strcpy ((char *) malloc (strlen ((str)) + 1), (str)))) 1.1 root 74: #define SFREE(str) (str != NULL && (free(str),0)) 75: 76: #define STREQL(s1,s2) (strcmp((s1),(s2)) == 0) 77: #define STRNEQ(s1,s2) (strcmp((s1),(s2)) != 0) 78: #define STRLSS(s1,s2) (strcmp((s1),(s2)) < 0) 79: #define STRLEQ(s1,s2) (strcmp((s1),(s2)) <= 0) 80: #define STRGTR(s1,s2) (strcmp((s1),(s2)) > 0) 81: #define STRGEQ(s1,s2) (strcmp((s1),(s2)) >= 0) 82: 83: /************************************************************************/ 84: /* */ 85: /* Type definitions */ 86: /* */ 87: /************************************************************************/ 88: 89: 90: typedef struct _XREF_FILE * XREF_FILE; 91: typedef struct _XREF_SCOPE * XREF_SCOPE; 92: 93: typedef struct _XREF_FILE 94: { 1.1.1.4 root 95: char *name; 96: char *outname; 1.1 root 97: XREF_FILE next; 98: } XREF_FILE_INFO; 99: 100: typedef struct _XREF_SCOPE 101: { 1.1.1.4 root 102: int gid; 103: int lid; 1.1 root 104: XREF_FILE file; 1.1.1.4 root 105: int start; 1.1 root 106: XREF_SCOPE outer; 107: } XREF_SCOPE_INFO; 108: 109: /************************************************************************/ 110: /* */ 111: /* Local storage */ 112: /* */ 113: /************************************************************************/ 114: 115: static char doing_xref = 0; 116: static FILE * xref_file = NULL; 117: static char xref_name[1024]; 118: static XREF_FILE all_files = NULL; 1.1.1.4 root 119: static char * wd_name = NULL; 1.1 root 120: static XREF_SCOPE cur_scope = NULL; 1.1.1.4 root 121: static int scope_ctr = 0; 1.1 root 122: static XREF_FILE last_file = NULL; 123: static tree last_fndecl = NULL; 124: 125: /************************************************************************/ 126: /* */ 127: /* Forward definitions */ 128: /* */ 129: /************************************************************************/ 130: 131: extern void GNU_xref_begin(); 132: extern void GNU_xref_end(); 133: extern void GNU_xref_file(); 134: extern void GNU_xref_start_scope(); 135: extern void GNU_xref_end_scope(); 136: extern void GNU_xref_ref(); 137: extern void GNU_xref_decl(); 138: extern void GNU_xref_call(); 139: extern void GNU_xref_function(); 140: extern void GNU_xref_assign(); 141: extern void GNU_xref_hier(); 142: extern void GNU_xref_member(); 143: 144: static void gen_assign(); 145: static XREF_FILE find_file(); 1.1.1.4 root 146: static char * filename(); 147: static char * fctname(); 148: static char * declname(); 1.1 root 149: static void simplify_type(); 1.1.1.4 root 150: static char * fixname(); 1.1 root 151: static void open_xref_file(); 152: 153: extern char * type_as_string(); 154: 155: /* Start cross referencing. FILE is the name of the file we xref. */ 156: 157: void 158: GNU_xref_begin (file) 1.1.1.4 root 159: char *file; 1.1 root 160: { 161: doing_xref = 1; 162: 163: if (file != NULL && STRNEQ (file,"-")) 164: { 165: open_xref_file(file); 166: GNU_xref_file(file); 167: } 168: } 169: 170: /* Finish cross-referencing. ERRCNT is the number of errors 171: we encountered. */ 172: 173: void 174: GNU_xref_end (ect) 175: int ect; 176: { 177: XREF_FILE xf; 178: 179: if (!doing_xref) return; 180: 181: xf = find_file (input_filename); 182: if (xf == NULL) return; 183: 184: while (cur_scope != NULL) 185: GNU_xref_end_scope(cur_scope->gid,0,0,0,0); 186: 187: doing_xref = 0; 188: 189: if (xref_file == NULL) return; 190: 191: fclose (xref_file); 192: 193: xref_file = NULL; 194: all_files = NULL; 195: 196: if (ect > 0) unlink (xref_name); 197: } 198: 199: /* Write out xref for file named NAME. */ 200: 201: void 202: GNU_xref_file (name) 1.1.1.4 root 203: char *name; 1.1 root 204: { 205: XREF_FILE xf; 206: 207: if (!doing_xref || name == NULL) return; 208: 209: if (xref_file == NULL) 210: { 211: open_xref_file (name); 212: if (!doing_xref) return; 213: } 214: 215: if (all_files == NULL) 216: fprintf(xref_file,"SCP * 0 0 0 0 RESET\n"); 217: 218: xf = find_file (name); 219: if (xf != NULL) return; 220: 221: xf = PALLOC (XREF_FILE_INFO); 222: xf->name = SALLOC (name); 223: xf->next = all_files; 224: all_files = xf; 225: 226: if (wd_name == NULL) 1.1.1.2 root 227: wd_name = getpwd (); 1.1 root 228: 1.1.1.2 root 229: if (FILE_NAME_ABSOLUTE_P (name) || ! wd_name) 1.1 root 230: xf->outname = xf->name; 231: else 232: { 1.1.1.2 root 233: char *nmbuf 234: = (char *) malloc (strlen (wd_name) + strlen (FILE_NAME_JOINER) 235: + strlen (name) + 1); 236: sprintf (nmbuf, "%s%s%s", wd_name, FILE_NAME_JOINER, name); 1.1 root 237: name = nmbuf; 1.1.1.2 root 238: xf->outname = nmbuf; 1.1 root 239: } 240: 241: fprintf (xref_file, "FIL %s %s 0\n", name, wd_name); 242: 1.1.1.2 root 243: filename (xf); 244: fctname (NULL); 1.1 root 245: } 246: 247: /* Start a scope identified at level ID. */ 248: 249: void 250: GNU_xref_start_scope (id) 1.1.1.4 root 251: HOST_WIDE_INT id; 1.1 root 252: { 253: XREF_SCOPE xs; 254: XREF_FILE xf; 255: 256: if (!doing_xref) return; 257: xf = find_file (input_filename); 258: 259: xs = PALLOC (XREF_SCOPE_INFO); 260: xs->file = xf; 261: xs->start = lineno; 262: if (xs->start <= 0) xs->start = 1; 263: xs->gid = id; 264: xs->lid = ++scope_ctr; 265: xs->outer = cur_scope; 266: cur_scope = xs; 267: } 268: 269: /* Finish a scope at level ID. 270: INID is ??? 271: PRM is ??? 272: KEEP is nonzero iff this scope is retained (nonzero if it's 273: a compiler-generated invisible scope). 274: TRNS is ??? */ 275: 276: void 277: GNU_xref_end_scope (id,inid,prm,keep,trns) 1.1.1.4 root 278: HOST_WIDE_INT id; 279: HOST_WIDE_INT inid; 280: int prm,keep,trns; 1.1 root 281: { 282: XREF_FILE xf; 283: XREF_SCOPE xs,lxs,oxs; 1.1.1.4 root 284: char *stype; 1.1 root 285: 286: if (!doing_xref) return; 287: xf = find_file (input_filename); 288: if (xf == NULL) return; 289: 290: lxs = NULL; 291: for (xs = cur_scope; xs != NULL; xs = xs->outer) 292: { 293: if (xs->gid == id) break; 294: lxs = xs; 295: } 296: if (xs == NULL) return; 297: 298: if (inid != 0) { 299: for (oxs = cur_scope; oxs != NULL; oxs = oxs->outer) { 300: if (oxs->gid == inid) break; 301: } 302: if (oxs == NULL) return; 303: inid = oxs->lid; 304: } 305: 306: if (prm == 2) stype = "SUE"; 307: else if (prm != 0) stype = "ARGS"; 308: else if (keep == 2 || inid != 0) stype = "INTERN"; 309: else stype = "EXTERN"; 310: 311: fprintf (xref_file,"SCP %s %d %d %d %d %s\n", 312: filename (xf), xs->start, lineno,xs->lid, inid, stype); 313: 314: if (lxs == NULL) cur_scope = xs->outer; 315: else lxs->outer = xs->outer; 316: 317: free (xs); 318: } 319: 320: /* Output a reference to NAME in FNDECL. */ 321: 322: void 323: GNU_xref_ref (fndecl,name) 324: tree fndecl; 1.1.1.4 root 325: char *name; 1.1 root 326: { 327: XREF_FILE xf; 328: 329: if (!doing_xref) return; 330: xf = find_file (input_filename); 331: if (xf == NULL) return; 332: 333: fprintf (xref_file, "REF %s %d %s %s\n", 334: filename (xf), lineno, fctname (fndecl), name); 335: } 336: 337: /* Output a reference to DECL in FNDECL. */ 338: 339: void 340: GNU_xref_decl (fndecl,decl) 341: tree fndecl; 342: tree decl; 343: { 344: XREF_FILE xf,xf1; 1.1.1.4 root 345: char *cls; 346: char *name; 1.1 root 347: char buf[10240]; 1.1.1.4 root 348: int uselin; 1.1 root 349: 350: if (!doing_xref) return; 351: xf = find_file (input_filename); 352: if (xf == NULL) return; 353: 354: uselin = FALSE; 355: 356: if (TREE_CODE (decl) == TYPE_DECL) cls = "TYPEDEF"; 357: else if (TREE_CODE (decl) == FIELD_DECL) cls = "FIELD"; 358: else if (TREE_CODE (decl) == VAR_DECL) 359: { 360: if (fndecl == NULL && TREE_STATIC(decl) 361: && TREE_READONLY(decl) && DECL_INITIAL(decl) != 0 1.1.1.3 root 362: && !TREE_PUBLIC(decl) && !DECL_EXTERNAL(decl) 1.1 root 363: && DECL_MODE(decl) != BLKmode) cls = "CONST"; 1.1.1.3 root 364: else if (DECL_EXTERNAL(decl)) cls = "EXTERN"; 1.1 root 365: else if (TREE_PUBLIC(decl)) cls = "EXTDEF"; 366: else if (TREE_STATIC(decl)) cls = "STATIC"; 1.1.1.3 root 367: else if (DECL_REGISTER(decl)) cls = "REGISTER"; 1.1 root 368: else cls = "AUTO"; 369: } 370: else if (TREE_CODE (decl) == PARM_DECL) cls = "PARAM"; 371: else if (TREE_CODE (decl) == FIELD_DECL) cls = "FIELD"; 372: else if (TREE_CODE (decl) == CONST_DECL) cls = "CONST"; 373: else if (TREE_CODE (decl) == FUNCTION_DECL) 374: { 1.1.1.3 root 375: if (DECL_EXTERNAL (decl)) cls = "EXTERN"; 1.1 root 376: else if (TREE_PUBLIC (decl)) cls = "EFUNCTION"; 377: else cls = "SFUNCTION"; 378: } 379: else if (TREE_CODE (decl) == LABEL_DECL) cls = "LABEL"; 380: else if (TREE_CODE (decl) == UNION_TYPE) 381: { 382: cls = "UNIONID"; 383: decl = TYPE_NAME (decl); 384: uselin = TRUE; 385: } 386: else if (TREE_CODE (decl) == RECORD_TYPE) 387: { 388: if (CLASSTYPE_DECLARED_CLASS (decl)) cls = "CLASSID"; 389: else cls = "STRUCTID"; 390: decl = TYPE_NAME (decl); 391: uselin = TRUE; 392: } 393: else if (TREE_CODE (decl) == ENUMERAL_TYPE) 394: { 395: cls = "ENUMID"; 396: decl = TYPE_NAME (decl); 397: uselin = TRUE; 398: } 399: else cls = "UNKNOWN"; 400: 401: if (decl == NULL || DECL_NAME (decl) == NULL) return; 402: 403: if (uselin && decl->decl.linenum > 0 && decl->decl.filename != NULL) 404: { 405: xf1 = find_file (decl->decl.filename); 406: if (xf1 != NULL) 407: { 408: lineno = decl->decl.linenum; 409: xf = xf1; 410: } 411: } 412: 413: if (DECL_ASSEMBLER_NAME (decl)) 414: name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); 415: else 416: name = IDENTIFIER_POINTER (DECL_NAME (decl)); 417: 1.1.1.5 ! root 418: strcpy (buf, type_as_string (TREE_TYPE (decl), 0)); 1.1 root 419: simplify_type (buf); 420: 421: fprintf (xref_file, "DCL %s %d %s %d %s %s %s\n", 422: filename(xf), lineno, name, 423: (cur_scope != NULL ? cur_scope->lid : 0), 424: cls, fctname(fndecl), buf); 425: 426: if (STREQL (cls, "STRUCTID") || STREQL (cls, "UNIONID")) 427: { 428: cls = "CLASSID"; 429: fprintf (xref_file, "DCL %s %d %s %d %s %s %s\n", 430: filename(xf), lineno,name, 431: (cur_scope != NULL ? cur_scope->lid : 0), 432: cls, fctname(fndecl), buf); 433: } 434: } 435: 436: /* Output a reference to a call to NAME in FNDECL. */ 437: 438: void 439: GNU_xref_call (fndecl, name) 440: tree fndecl; 1.1.1.4 root 441: char *name; 1.1 root 442: { 443: XREF_FILE xf; 444: char buf[1024]; 1.1.1.4 root 445: char *s; 1.1 root 446: 447: if (!doing_xref) return; 448: xf = find_file (input_filename); 449: if (xf == NULL) return; 450: name = fixname (name, buf); 451: 452: for (s = name; *s != 0; ++s) 453: if (*s == '_' && s[1] == '_') break; 454: if (*s != 0) GNU_xref_ref (fndecl, name); 455: 456: fprintf (xref_file, "CAL %s %d %s %s\n", 457: filename (xf), lineno, name, fctname (fndecl)); 458: } 459: 460: /* Output cross-reference info about FNDECL. If non-NULL, 461: ARGS are the arguments for the function (i.e., before the FUNCTION_DECL 462: has been fully built). */ 463: 464: void 465: GNU_xref_function (fndecl, args) 466: tree fndecl; 467: tree args; 468: { 469: XREF_FILE xf; 470: int ct; 471: char buf[1024]; 472: 473: if (!doing_xref) return; 474: xf = find_file (input_filename); 475: if (xf == NULL) return; 476: 477: ct = 0; 478: buf[0] = 0; 479: if (args == NULL) args = DECL_ARGUMENTS (fndecl); 480: 481: GNU_xref_decl (NULL, fndecl); 482: 483: for ( ; args != NULL; args = TREE_CHAIN (args)) 484: { 485: GNU_xref_decl (fndecl,args); 486: if (ct != 0) strcat (buf,","); 487: strcat (buf, declname (args)); 488: ++ct; 489: } 490: 491: fprintf (xref_file, "PRC %s %d %s %d %d %s\n", 492: filename(xf), lineno, declname(fndecl), 493: (cur_scope != NULL ? cur_scope->lid : 0), 494: ct, buf); 495: } 496: 497: /* Output cross-reference info about an assignment to NAME. */ 498: 499: void 500: GNU_xref_assign(name) 501: tree name; 502: { 503: XREF_FILE xf; 504: 505: if (!doing_xref) return; 506: xf = find_file(input_filename); 507: if (xf == NULL) return; 508: 509: gen_assign(xf, name); 510: } 511: 512: static void 513: gen_assign(xf, name) 514: XREF_FILE xf; 515: tree name; 516: { 1.1.1.4 root 517: char *s; 1.1 root 518: 519: s = NULL; 520: 521: switch (TREE_CODE (name)) 522: { 523: case IDENTIFIER_NODE : 524: s = IDENTIFIER_POINTER(name); 525: break; 526: case VAR_DECL : 527: s = declname(name); 528: break; 529: case COMPONENT_REF : 530: gen_assign(xf, TREE_OPERAND(name, 0)); 531: gen_assign(xf, TREE_OPERAND(name, 1)); 532: break; 533: case INDIRECT_REF : 534: case OFFSET_REF : 535: case ARRAY_REF : 536: case BUFFER_REF : 537: gen_assign(xf, TREE_OPERAND(name, 0)); 538: break; 539: case COMPOUND_EXPR : 540: gen_assign(xf, TREE_OPERAND(name, 1)); 541: break; 542: default : 543: break; 544: } 545: 546: if (s != NULL) 547: fprintf(xref_file, "ASG %s %d %s\n", filename(xf), lineno, s); 548: } 549: 550: /* Output cross-reference info about a class hierarchy. 551: CLS is the class type of interest. BASE is a baseclass 552: for CLS. PUB and VIRT give the visibility info about 553: the class derivation. FRND is nonzero iff BASE is a friend 554: of CLS. 555: 556: ??? Needs to handle nested classes. */ 557: void 558: GNU_xref_hier(cls, base, pub, virt, frnd) 1.1.1.4 root 559: char *cls; 560: char *base; 1.1 root 561: int pub; 562: int virt; 563: int frnd; 564: { 565: XREF_FILE xf; 566: 567: if (!doing_xref) return; 568: xf = find_file(input_filename); 569: if (xf == NULL) return; 570: 571: fprintf(xref_file, "HIE %s %d %s %s %d %d %d\n", 572: filename(xf), lineno, cls, base, pub, virt, frnd); 573: } 574: 575: /* Output cross-reference info about class members. CLS 576: is the containing type; FLD is the class member. */ 577: 578: void 579: GNU_xref_member(cls, fld) 580: tree cls; 581: tree fld; 582: { 583: XREF_FILE xf; 1.1.1.4 root 584: char *prot; 585: int confg, pure; 586: char *d; 587: int i; 1.1 root 588: char buf[1024], bufa[1024]; 589: 590: if (!doing_xref) return; 591: xf = find_file(fld->decl.filename); 592: if (xf == NULL) return; 593: 594: if (TREE_PRIVATE (fld)) prot = "PRIVATE"; 595: else if (TREE_PROTECTED(fld)) prot = "PROTECTED"; 596: else prot = "PUBLIC"; 597: 598: confg = 0; 599: if (TREE_CODE (fld) == FUNCTION_DECL && DECL_CONST_MEMFUNC_P(fld)) 600: confg = 1; 601: else if (TREE_CODE (fld) == CONST_DECL) 602: confg = 1; 603: 604: pure = 0; 605: if (TREE_CODE (fld) == FUNCTION_DECL && DECL_ABSTRACT_VIRTUAL_P(fld)) 606: pure = 1; 607: 608: d = IDENTIFIER_POINTER(cls); 609: sprintf(buf, "%d%s", strlen(d), d); 610: i = strlen(buf); 611: strcpy(bufa, declname(fld)); 612: 613: #ifdef XREF_SHORT_MEMBER_NAMES 614: for (p = &bufa[1]; *p != 0; ++p) 615: { 616: if (p[0] == '_' && p[1] == '_' && p[2] >= '0' && p[2] <= '9') { 617: if (strncmp(&p[2], buf, i) == 0) *p = 0; 618: break; 619: } 620: else if (p[0] == '_' && p[1] == '_' && p[2] == 'C' && p[3] >= '0' && p[3] <= '9') { 621: if (strncmp(&p[3], buf, i) == 0) *p = 0; 622: break; 623: } 624: } 625: #endif 626: 627: fprintf(xref_file, "MEM %s %d %s %s %s %d %d %d %d %d %d %d\n", 628: filename(xf), fld->decl.linenum, d, bufa, prot, 629: (TREE_CODE (fld) == FUNCTION_DECL ? 0 : 1), 1.1.1.3 root 630: (DECL_INLINE (fld) ? 1 : 0), 1.1 root 631: (DECL_FRIEND_P(fld) ? 1 : 0), 632: (DECL_VINDEX(fld) ? 1 : 0), 633: (TREE_STATIC(fld) ? 1 : 0), 634: pure, confg); 635: } 636: 637: /* Find file entry given name. */ 638: 639: static XREF_FILE 640: find_file(name) 1.1.1.4 root 641: char *name; 1.1 root 642: { 643: XREF_FILE xf; 644: 645: for (xf = all_files; xf != NULL; xf = xf->next) { 646: if (STREQL(name, xf->name)) break; 647: } 648: 649: return xf; 650: } 651: 652: /* Return filename for output purposes. */ 653: 1.1.1.4 root 654: static char * 1.1 root 655: filename(xf) 656: XREF_FILE xf; 657: { 658: if (xf == NULL) { 659: last_file = NULL; 660: return "*"; 661: } 662: 663: if (last_file == xf) return "*"; 664: 665: last_file = xf; 666: 667: return xf->outname; 668: } 669: 670: /* Return function name for output purposes. */ 671: 1.1.1.4 root 672: static char * 1.1 root 673: fctname(fndecl) 674: tree fndecl; 675: { 676: static char fctbuf[1024]; 1.1.1.4 root 677: char *s; 1.1 root 678: 679: if (fndecl == NULL && last_fndecl == NULL) return "*"; 680: 681: if (fndecl == NULL) 682: { 683: last_fndecl = NULL; 684: return "*TOP*"; 685: } 686: 687: if (fndecl == last_fndecl) return "*"; 688: 689: last_fndecl = fndecl; 690: 691: s = declname(fndecl); 692: s = fixname(s, fctbuf); 693: 694: return s; 695: } 696: 697: /* Return decl name for output purposes. */ 698: 1.1.1.4 root 699: static char * 1.1 root 700: declname(dcl) 701: tree dcl; 702: { 703: if (DECL_NAME (dcl) == NULL) return "?"; 704: 705: if (DECL_ASSEMBLER_NAME (dcl)) 706: return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (dcl)); 707: else 708: return IDENTIFIER_POINTER (DECL_NAME (dcl)); 709: } 710: 711: /* Simplify a type string by removing unneeded parenthesis. */ 712: 713: static void 714: simplify_type(typ) 1.1.1.4 root 715: char *typ; 1.1 root 716: { 1.1.1.4 root 717: char *s; 718: int lvl, i; 1.1 root 719: 720: i = strlen(typ); 721: while (i > 0 && isspace(typ[i-1])) typ[--i] = 0; 722: 723: if (i > 7 && STREQL(&typ[i-5], "const")) 724: { 725: typ[i-5] = 0; 726: i -= 5; 727: } 728: 729: if (typ[i-1] != ')') return; 730: 731: s = &typ[i-2]; 732: lvl = 1; 733: while (*s != 0) { 734: if (*s == ')') ++lvl; 735: else if (*s == '(') 736: { 737: --lvl; 738: if (lvl == 0) 739: { 740: s[1] = ')'; 741: s[2] = 0; 742: break; 743: } 744: } 745: --s; 746: } 747: 748: if (*s != 0 && s[-1] == ')') 749: { 750: --s; 751: --s; 752: if (*s == '(') s[2] = 0; 753: else if (*s == ':') { 754: while (*s != '(') --s; 755: s[1] = ')'; 756: s[2] = 0; 757: } 758: } 759: } 760: 761: /* Fixup a function name (take care of embedded spaces). */ 762: 1.1.1.4 root 763: static char * 1.1 root 764: fixname(nam, buf) 1.1.1.4 root 765: char *nam; 766: char *buf; 1.1 root 767: { 1.1.1.4 root 768: char *s, *t; 1.1 root 769: int fg; 770: 771: s = nam; 772: t = buf; 773: fg = 0; 774: 775: while (*s != 0) 776: { 777: if (*s == ' ') 778: { 779: *t++ = '\36'; 780: ++fg; 781: } 782: else *t++ = *s; 783: ++s; 784: } 785: *t = 0; 786: 787: if (fg == 0) return nam; 788: 789: return buf; 790: } 791: 792: /* Open file for xrefing. */ 793: 794: static void 795: open_xref_file(file) 1.1.1.4 root 796: char *file; 1.1 root 797: { 1.1.1.4 root 798: char *s, *t; 1.1 root 799: 800: #ifdef XREF_FILE_NAME 801: XREF_FILE_NAME (xref_name, file); 802: #else 803: s = rindex (file, '/'); 804: if (s == NULL) 805: sprintf (xref_name, ".%s.gxref", file); 806: else 807: { 808: ++s; 809: strcpy (xref_name, file); 810: t = rindex (xref_name, '/'); 811: ++t; 812: *t++ = '.'; 813: strcpy (t, s); 814: strcat (t, ".gxref"); 815: } 816: #endif /* no XREF_FILE_NAME */ 817: 818: xref_file = fopen(xref_name, "w"); 819: 820: if (xref_file == NULL) 821: { 822: error("Can't create cross-reference file `%s'", xref_name); 823: doing_xref = 0; 824: } 825: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.