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