home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume14 / dmake / part19 < prev    next >
Encoding:
Text File  |  1990-07-26  |  38.7 KB  |  1,253 lines

  1. Newsgroups: comp.sources.misc
  2. subject: v14i029: dmake version 3.5 part 19/21
  3. From: dvadura@watdragon.waterloo.edu (Dennis Vadura)
  4. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5.  
  6. Posting-number: Volume 14, Issue 29
  7. Submitted-by: dvadura@watdragon.waterloo.edu (Dennis Vadura)
  8. Archive-name: dmake/part19
  9.  
  10. #!/bin/sh
  11. # this is part 19 of a multipart archive
  12. # do not concatenate these parts, unpack them in order with /bin/sh
  13. # file common/malloc.c continued
  14. #
  15. CurArch=19
  16. if test ! -r s2_seq_.tmp
  17. then echo "Please unpack part 1 first!"
  18.      exit 1; fi
  19. ( read Scheck
  20.   if test "$Scheck" != $CurArch
  21.   then echo "Please unpack part $Scheck next!"
  22.        exit 1;
  23.   else exit 0; fi
  24. ) < s2_seq_.tmp || exit 1
  25. echo "x - Continuing file common/malloc.c"
  26. sed 's/^X//' << 'SHAR_EOF' >> common/malloc.c
  27. X    }
  28. X    for (blk = _fab; blk != (struct _Dmi *) 0; blk = blk->m_next) {
  29. X        if ((char *) blk + sizeof *blk + blk->m_size - 1 > send) {
  30. X            _malldstr("(brk = ");
  31. X            _malldptr(send);
  32. X            _malldstr(", eblk = ");
  33. X            _malldptr((char *) blk + sizeof *blk + blk->m_size - 1);
  34. X            _malldstr(")\n");
  35. X            _mallerr(fn, "allocated block extends past brk: ", blk);
  36. X        }
  37. X        cnt = 0;
  38. X        for (cblk = _fab; cblk != (struct _Dmi *) 0; cblk = cblk->m_next) {
  39. X            if (blk == cblk)
  40. X                if (cnt++ == 0)
  41. X                    continue;
  42. X                else
  43. X                    _mallerr(fn, "block allocated twice: ", blk);
  44. X            if (blk > cblk && (char *) blk < (char *) cblk + sizeof *cblk + cblk->m_size - 1) {
  45. X                _malldstr("(blk = ");
  46. X                _malldptr(blk);
  47. X                _malldstr(", cblk = ");
  48. X                _malldptr((char *) cblk + sizeof *cblk + cblk->m_size - 1);
  49. X                _malldstr(")\n");
  50. X                _mallerr(fn, "nested block in allocated list: ", blk);
  51. X            }
  52. X        }
  53. X        for (cblk = _ffb; cblk != (struct _Dmi *) 0; cblk = cblk->m_next) {
  54. X            if (blk == cblk)
  55. X                _mallerr(fn, "block on allocated and free lists: ", blk);
  56. X            if (blk > cblk && (char *) blk < (char *) cblk + sizeof *cblk + cblk->m_size - 1) {
  57. X                _malldstr("(blk = ");
  58. X                _malldptr(blk);
  59. X                _malldstr(", cblk = ");
  60. X                _malldptr((char *) cblk + sizeof *cblk + cblk->m_size - 1);
  61. X                _malldstr(")\n");
  62. X                _mallerr(fn, "allocated block nested in free block: ", blk);
  63. X            }
  64. X        }
  65. X    }
  66. X    for (blk = _ffb; blk != (struct _Dmi *) 0; blk = blk->m_next) {
  67. X        if ((char *) blk + sizeof *blk + blk->m_size - 1 > send) {
  68. X            _malldstr("(brk = ");
  69. X            _malldptr(send);
  70. X            _malldstr(", eblk = ");
  71. X            _malldptr((char *) blk + sizeof *blk + blk->m_size - 1);
  72. X            _malldstr(")\n");
  73. X            _mallerr(fn, "free block extends past brk: ", blk);
  74. X        }
  75. X        cnt = 0;
  76. X        for (cblk = _ffb; cblk != (struct _Dmi *) 0; cblk = cblk->m_next) {
  77. X            if (blk == cblk)
  78. X                if (cnt++ == 0)
  79. X                    continue;
  80. X                else
  81. X                    _mallerr(fn, "block freed twice: ", blk);
  82. X            if (blk > cblk && (char *) blk < (char *) cblk + sizeof *cblk + cblk->m_size - 1) {
  83. X                _malldstr("(blk = ");
  84. X                _malldptr(blk);
  85. X                _malldstr(", cblk = ");
  86. X                _malldptr((char *) cblk + sizeof *cblk + cblk->m_size - 1);
  87. X                _malldstr(")\n");
  88. X                _mallerr(fn, "nested block in free list: ", blk);
  89. X            }
  90. X        }
  91. X        for (cblk = _fab; cblk != (struct _Dmi *) 0; cblk = cblk->m_next) {
  92. X            if (blk == cblk)
  93. X                _mallerr(fn, "block on allocated and free lists: ", blk);
  94. X            if (blk > cblk && (char *) blk < (char *) cblk + sizeof *cblk + cblk->m_size - 1) {
  95. X                _malldstr("(blk = ");
  96. X                _malldptr(blk);
  97. X                _malldstr(", cblk = ");
  98. X                _malldptr((char *) cblk + sizeof *cblk + cblk->m_size - 1);
  99. X                _malldstr(")\n");
  100. X                _mallerr(fn, "free block nested in allocated block: ", blk);
  101. X            }
  102. X        }
  103. X    }
  104. X}
  105. X
  106. X/*
  107. X * malloc objects and zero storage
  108. X */
  109. X
  110. Xchar *calloc(n, size )
  111. Xregister unsigned n, size;
  112. X{
  113. X    register char *s, *s1;
  114. X
  115. X    if (_mall_opt)
  116. X    {
  117. X         _malldstr("calloc: num: ");
  118. X         _malldptr(n);
  119. X         _malldstr( " size: " );
  120. X         _malldptr(size);
  121. X         _malldstr("\n");
  122. X    }
  123. X    n *= size;
  124. X    if ((s = malloc(n)) == (char *) 0)
  125. X        return (char *) 0;
  126. X    for (s1 = s; n != 0; n--)
  127. X        *s1++ = 0;
  128. X    return s;
  129. X}
  130. X
  131. X/*
  132. X * for some reason this is in /lib/libc.a(calloc.o)
  133. X */
  134. X
  135. Xcfree(s)
  136. Xchar *s; {
  137. X    free(s);
  138. X}
  139. X#endif
  140. X#endif
  141. X
  142. SHAR_EOF
  143. echo "File common/malloc.c is complete"
  144. chmod 0440 common/malloc.c || echo "restore of common/malloc.c fails"
  145. echo "x - extracting common/macros.h (Text)"
  146. sed 's/^X//' << 'SHAR_EOF' > common/macros.h &&
  147. X/* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/common/RCS/macros.h,v 1.1 90/07/19 13:30:46 dvadura Exp $
  148. X-- SYNOPSIS -- general use macros.
  149. X-- 
  150. X-- DESCRIPTION
  151. X--     ANSI macro relies on the fact that it can be replaced by (), or by
  152. X--    its value, where the value is one value due to the preprocessors
  153. X--    handling of arguments that are surrounded by ()'s as a single
  154. X--    argument.
  155. X--
  156. X-- AUTHOR
  157. X--      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  158. X--      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  159. X--
  160. X-- COPYRIGHT
  161. X--      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  162. X-- 
  163. X--      This program is free software; you can redistribute it and/or
  164. X--      modify it under the terms of the GNU General Public License
  165. X--      (version 1), as published by the Free Software Foundation, and
  166. X--      found in the file 'LICENSE' included with this distribution.
  167. X-- 
  168. X--      This program is distributed in the hope that it will be useful,
  169. X--      but WITHOUT ANY WARRANTY; without even the implied warrant of
  170. X--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  171. X--      GNU General Public License for more details.
  172. X-- 
  173. X--      You should have received a copy of the GNU General Public License
  174. X--      along with this program;  if not, write to the Free Software
  175. X--      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  176. X--
  177. X-- LOG
  178. X--     $Log:    macros.h,v $
  179. X * Revision 1.1  90/07/19  13:30:46  dvadura
  180. X * Initial Revision of Version 3.5
  181. X * 
  182. X*/
  183. X
  184. X#ifndef    MACROS_h
  185. X#define    MACROS_h
  186. X
  187. X#if defined(__STDC__) || defined(__TURBOC__)
  188. X#define    ANSI(x)    x
  189. X#else
  190. X#define    ANSI(x)    ()
  191. X#endif
  192. X
  193. X#define    NIL(p)    ((p*)NULL)
  194. X#define    offsetof(type,id) ((size_t)&((type*)NULL)->id)
  195. X
  196. X#define    FALSE    0
  197. X#define    TRUE    1
  198. X
  199. X#endif
  200. X
  201. SHAR_EOF
  202. chmod 0440 common/macros.h || echo "restore of common/macros.h fails"
  203. echo "x - extracting common/itypes.h (Text)"
  204. sed 's/^X//' << 'SHAR_EOF' > common/itypes.h &&
  205. X/* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/common/RCS/itypes.h,v 1.1 90/07/19 13:30:45 dvadura Exp $
  206. X-- SYNOPSIS -- type declarations for common types
  207. X-- 
  208. X-- DESCRIPTION
  209. X--     portable type declarations.
  210. X--
  211. X-- AUTHOR
  212. X--      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  213. X--      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  214. X--
  215. X-- COPYRIGHT
  216. X--      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  217. X-- 
  218. X--      This program is free software; you can redistribute it and/or
  219. X--      modify it under the terms of the GNU General Public License
  220. X--      (version 1), as published by the Free Software Foundation, and
  221. X--      found in the file 'LICENSE' included with this distribution.
  222. X-- 
  223. X--      This program is distributed in the hope that it will be useful,
  224. X--      but WITHOUT ANY WARRANTY; without even the implied warrant of
  225. X--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  226. X--      GNU General Public License for more details.
  227. X-- 
  228. X--      You should have received a copy of the GNU General Public License
  229. X--      along with this program;  if not, write to the Free Software
  230. X--      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  231. X--
  232. X-- LOG
  233. X--     $Log:    itypes.h,v $
  234. X * Revision 1.1  90/07/19  13:30:45  dvadura
  235. X * Initial Revision of Version 3.5
  236. X * 
  237. X*/
  238. X
  239. X
  240. X#ifndef ITYPES_h
  241. X#define    ITYPES_h
  242. X
  243. X#if defined(M_I86) || defined(MC68000)
  244. Xtypedef char  int8;               /* typedefs for right size ints */
  245. Xtypedef int   int16;
  246. Xtypedef long  int32;
  247. Xtypedef unsigned char  uint8;
  248. Xtypedef unsigned int   uint16;
  249. Xtypedef unsigned long  uint32;
  250. X#else
  251. Xtypedef char  int8;               /* typedefs for right size ints */
  252. Xtypedef short int16;
  253. Xtypedef long  int32;
  254. Xtypedef unsigned char  uint8;
  255. Xtypedef unsigned short uint16;
  256. Xtypedef unsigned long  uint32;
  257. X#endif
  258. X
  259. X#endif
  260. X
  261. SHAR_EOF
  262. chmod 0440 common/itypes.h || echo "restore of common/itypes.h fails"
  263. echo "x - extracting common/dbug.h (Text)"
  264. sed 's/^X//' << 'SHAR_EOF' > common/dbug.h &&
  265. X/******************************************************************************
  266. X *                                          *
  267. X *                               N O T I C E                      *
  268. X *                                          *
  269. X *                  Copyright Abandoned, 1987, Fred Fish              *
  270. X *                                          *
  271. X *                                          *
  272. X *    This previously copyrighted work has been placed into the  public     *
  273. X *    domain  by  the  author  and  may be freely used for any purpose,     *
  274. X *    private or commercial.                              *
  275. X *                                          *
  276. X *    Because of the number of inquiries I was receiving about the  use     *
  277. X *    of this product in commercially developed works I have decided to     *
  278. X *    simply make it public domain to further its unrestricted use.   I     *
  279. X *    specifically  would  be  most happy to see this material become a     *
  280. X *    part of the standard Unix distributions by AT&T and the  Berkeley     *
  281. X *    Computer  Science  Research Group, and a standard part of the GNU     *
  282. X *    system from the Free Software Foundation.                  *
  283. X *                                          *
  284. X *    I would appreciate it, as a courtesy, if this notice is  left  in     *
  285. X *    all copies and derivative works.  Thank you.                  *
  286. X *                                          *
  287. X *    The author makes no warranty of any kind  with  respect  to  this     *
  288. X *    product  and  explicitly disclaims any implied warranties of mer-     *
  289. X *    chantability or fitness for any particular purpose.              *
  290. X *                                          *
  291. X ******************************************************************************
  292. X */
  293. X
  294. X
  295. X/*
  296. X *  FILE
  297. X *
  298. X *    dbug.h    user include file for programs using the dbug package
  299. X *
  300. X *  SYNOPSIS
  301. X *
  302. X *    #include <local/dbug.h>
  303. X *
  304. X *  SCCS ID
  305. X *
  306. X *    @(#)dbug.h    1.11 9/5/87
  307. X *
  308. X *  DESCRIPTION
  309. X *
  310. X *    Programs which use the dbug package must include this file.
  311. X *    It contains the appropriate macros to call support routines
  312. X *    in the dbug runtime library.
  313. X *
  314. X *    To disable compilation of the macro expansions define the
  315. X *    preprocessor symbol "DBUG_OFF".  This will result in null
  316. X *    macros expansions so that the resulting code will be smaller
  317. X *    and faster.  (The difference may be smaller than you think
  318. X *    so this step is recommended only when absolutely necessary).
  319. X *    In general, tradeoffs between space and efficiency are
  320. X *    decided in favor of efficiency since space is seldom a
  321. X *    problem on the new machines).
  322. X *
  323. X *    All externally visible symbol names follow the pattern
  324. X *    "_db_xxx..xx_" to minimize the possibility of a dbug package
  325. X *    symbol colliding with a user defined symbol.
  326. X *    
  327. X *    The DBUG_<N> style macros are obsolete and should not be used
  328. X *    in new code.  Macros to map them to instances of DBUG_PRINT
  329. X *    are provided for compatibility with older code.  They may go
  330. X *    away completely in subsequent releases.
  331. X *
  332. X *  AUTHOR
  333. X *
  334. X *    Fred Fish
  335. X *    (Currently employed by Motorola Computer Division, Tempe, Az.)
  336. X *    hao!noao!mcdsun!fnf
  337. X *    (602) 438-3614
  338. X *
  339. X */
  340. X
  341. X
  342. X/*
  343. X *    Internally used dbug variables which must be global.
  344. X */
  345. X
  346. X#ifndef DBUG_OFF
  347. X    extern int _db_on_;            /* TRUE if debug currently enabled */
  348. X    extern FILE *_db_fp_;        /* Current debug output stream */
  349. X    extern char *_db_process_;        /* Name of current process */
  350. X    extern int _db_keyword_ ();        /* Accept/reject keyword */
  351. X    extern void _db_push_ ();        /* Push state, set up new state */
  352. X    extern void _db_pop_ ();        /* Pop previous debug state */
  353. X    extern void _db_enter_ ();        /* New user function entered */
  354. X    extern void _db_return_ ();        /* User function return */
  355. X    extern void _db_pargs_ ();        /* Remember args for line */
  356. X    extern void _db_doprnt_ ();        /* Print debug output */
  357. X    extern void _db_setjmp_ ();        /* Save debugger environment */
  358. X    extern void _db_longjmp_ ();    /* Restore debugger environment */
  359. X# endif
  360. X
  361. X
  362. X/*
  363. X *    These macros provide a user interface into functions in the
  364. X *    dbug runtime support library.  They isolate users from changes
  365. X *    in the MACROS and/or runtime support.
  366. X *
  367. X *    The symbols "__LINE__" and "__FILE__" are expanded by the
  368. X *    preprocessor to the current source file line number and file
  369. X *    name respectively.
  370. X *
  371. X *    WARNING ---  Because the DBUG_ENTER macro allocates space on
  372. X *    the user function's stack, it must precede any executable
  373. X *    statements in the user function.
  374. X *
  375. X */
  376. X
  377. X# ifdef DBUG_OFF
  378. X#    define DBUG_ENTER(a1)
  379. X#    define DBUG_RETURN(a1) return(a1)
  380. X#    define DBUG_VOID_RETURN return
  381. X#    define DBUG_EXECUTE(keyword,a1)
  382. X#    define DBUG_PRINT(keyword,arglist)
  383. X#    define DBUG_2(keyword,format)        /* Obsolete */
  384. X#    define DBUG_3(keyword,format,a1)        /* Obsolete */
  385. X#    define DBUG_4(keyword,format,a1,a2)    /* Obsolete */
  386. X#    define DBUG_5(keyword,format,a1,a2,a3)    /* Obsolete */
  387. X#    define DBUG_PUSH(a1)
  388. X#    define DBUG_POP()
  389. X#    define DBUG_PROCESS(a1)
  390. X#    define DBUG_FILE (stderr)
  391. X#    define DBUG_SETJMP setjmp
  392. X#    define DBUG_LONGJMP longjmp
  393. X# else
  394. X#    define DBUG_ENTER(a) \
  395. X    auto char *_db_func_, *_db_file_; \
  396. X    int _db_level_; \
  397. X    _db_enter_ (a,__FILE__,__LINE__,&_db_func_,&_db_file_,&_db_level_)
  398. X#    define DBUG_LEAVE \
  399. X    (_db_return_ (__LINE__, &_db_func_, &_db_file_, &_db_level_))
  400. X#    define DBUG_RETURN(a1) return (DBUG_LEAVE, (a1))
  401. X/*   define DBUG_RETURN(a1) {DBUG_LEAVE; return(a1);}  Alternate form */
  402. X#    define DBUG_VOID_RETURN DBUG_LEAVE; return
  403. X#    define DBUG_EXECUTE(keyword,a1) \
  404. X    {if (_db_on_) {if (_db_keyword_ (keyword)) { a1 }}}
  405. X#    define DBUG_PRINT(keyword,arglist) \
  406. X    {if (_db_on_) {_db_pargs_(__LINE__,keyword); _db_doprnt_ arglist;}}
  407. X#    define DBUG_2(keyword,format) \
  408. X    DBUG_PRINT(keyword,(format))        /* Obsolete */
  409. X#    define DBUG_3(keyword,format,a1) \
  410. X    DBUG_PRINT(keyword,(format,a1))        /* Obsolete */
  411. X#    define DBUG_4(keyword,format,a1,a2) \
  412. X    DBUG_PRINT(keyword,(format,a1,a2))    /* Obsolete */
  413. X#    define DBUG_5(keyword,format,a1,a2,a3) \
  414. X    DBUG_PRINT(keyword,(format,a1,a2,a3))    /* Obsolete */
  415. X#    define DBUG_PUSH(a1) _db_push_ (a1)
  416. X#    define DBUG_POP() _db_pop_ ()
  417. X#    define DBUG_PROCESS(a1) (_db_process_ = a1)
  418. X#    define DBUG_FILE (_db_fp_)
  419. X#    define DBUG_SETJMP(a1) (_db_setjmp_ (), setjmp (a1))
  420. X#    define DBUG_LONGJMP(a1,a2) (_db_longjmp_ (), longjmp (a1, a2))
  421. X# endif
  422. X
  423. SHAR_EOF
  424. chmod 0440 common/dbug.h || echo "restore of common/dbug.h fails"
  425. echo "x - extracting common/dbug.c (Text)"
  426. sed 's/^X//' << 'SHAR_EOF' > common/dbug.c &&
  427. X/******************************************************************************
  428. X *                                          *
  429. X *                               N O T I C E                      *
  430. X *                                          *
  431. X *                  Copyright Abandoned, 1987, Fred Fish              *
  432. X *                                          *
  433. X *                                          *
  434. X *    This previously copyrighted work has been placed into the  public     *
  435. X *    domain  by  the  author  and  may be freely used for any purpose,     *
  436. X *    private or commercial.                              *
  437. X *                                          *
  438. X *    Because of the number of inquiries I was receiving about the  use     *
  439. X *    of this product in commercially developed works I have decided to     *
  440. X *    simply make it public domain to further its unrestricted use.   I     *
  441. X *    specifically  would  be  most happy to see this material become a     *
  442. X *    part of the standard Unix distributions by AT&T and the  Berkeley     *
  443. X *    Computer  Science  Research Group, and a standard part of the GNU     *
  444. X *    system from the Free Software Foundation.                  *
  445. X *                                          *
  446. X *    I would appreciate it, as a courtesy, if this notice is  left  in     *
  447. X *    all copies and derivative works.  Thank you.                  *
  448. X *                                          *
  449. X *    The author makes no warranty of any kind  with  respect  to  this     *
  450. X *    product  and  explicitly disclaims any implied warranties of mer-     *
  451. X *    chantability or fitness for any particular purpose.              *
  452. X *                                          *
  453. X ******************************************************************************
  454. X */
  455. X
  456. X
  457. X/*
  458. X *  FILE
  459. X *
  460. X *    dbug.c   runtime support routines for dbug package
  461. X *
  462. X *  SCCS
  463. X *
  464. X *    @(#)dbug.c    1.19 9/5/87
  465. X *
  466. X *  DESCRIPTION
  467. X *
  468. X *    These are the runtime support routines for the dbug package.
  469. X *    The dbug package has two main components; the user include
  470. X *    file containing various macro definitions, and the runtime
  471. X *    support routines which are called from the macro expansions.
  472. X *
  473. X *    Externally visible functions in the runtime support module
  474. X *    use the naming convention pattern "_db_xx...xx_", thus
  475. X *    they are unlikely to collide with user defined function names.
  476. X *
  477. X *  AUTHOR(S)
  478. X *
  479. X *    Fred Fish        (base code)
  480. X *    (Currently at Motorola Computer Division, Tempe, Az.)
  481. X *    hao!noao!mcdsun!fnf
  482. X *    (602) 438-3614
  483. X *
  484. X *    Binayak Banerjee    (profiling enhancements)
  485. X *    seismo!bpa!sjuvax!bbanerje
  486. X */
  487. X
  488. X
  489. X#include <stdio.h>
  490. X#ifdef amiga
  491. X#define AMIGA
  492. X#endif
  493. X
  494. X#ifdef AMIGA
  495. X#define HZ (50)            /* Probably in some header somewhere */
  496. X#endif
  497. X
  498. X/*
  499. X *    Manifest constants that should not require any changes.
  500. X */
  501. X
  502. X#define FALSE        0    /* Boolean FALSE */
  503. X#define TRUE        1    /* Boolean TRUE */
  504. X#define EOS        '\000'    /* End Of String marker */
  505. X
  506. X/*
  507. X *    Manifest constants which may be "tuned" if desired.
  508. X */
  509. X
  510. X#define PRINTBUF    1024    /* Print buffer size */
  511. X#define INDENT        4    /* Indentation per trace level */
  512. X#define MAXDEPTH    200    /* Maximum trace depth default */
  513. X
  514. X/*
  515. X *    The following flags are used to determine which
  516. X *    capabilities the user has enabled with the state
  517. X *    push macro.
  518. X */
  519. X
  520. X#define TRACE_ON    000001    /* Trace enabled */
  521. X#define DEBUG_ON    000002    /* Debug enabled */
  522. X#define FILE_ON     000004    /* File name print enabled */
  523. X#define LINE_ON        000010    /* Line number print enabled */
  524. X#define DEPTH_ON    000020    /* Function nest level print enabled */
  525. X#define PROCESS_ON    000040    /* Process name print enabled */
  526. X#define NUMBER_ON    000100    /* Number each line of output */
  527. X#define PROFILE_ON    000200    /* Print out profiling code */
  528. X
  529. X#define TRACING (stack -> flags & TRACE_ON)
  530. X#define DEBUGGING (stack -> flags & DEBUG_ON)
  531. X#define PROFILING (stack -> flags & PROFILE_ON)
  532. X#define STREQ(a,b) (strcmp(a,b) == 0)
  533. X
  534. X/*
  535. X *    Typedefs to make things more obvious.
  536. X */
  537. X
  538. X#define VOID void        /* Can't use typedef for most compilers */
  539. Xtypedef int BOOLEAN;
  540. X
  541. X/*
  542. X *    Make it easy to change storage classes if necessary.
  543. X */
  544. X
  545. X#define LOCAL static        /* Names not needed by outside world */
  546. X#define IMPORT extern        /* Names defined externally */
  547. X#define EXPORT            /* Allocated here, available globally */
  548. X#define AUTO auto        /* Names to be allocated on stack */
  549. X#define REGISTER register    /* Names to be placed in registers */
  550. X
  551. X/*
  552. X *    The following define is for the variable arguments kluge, see
  553. X *    the comments in _db_doprnt_().
  554. X *
  555. X *    Also note that the longer this list, the less prone to failing
  556. X *    on long argument lists, but the more stuff that must be moved
  557. X *    around for each call to the runtime support routines.  The
  558. X *    length may really be critical if the machine convention is
  559. X *    to pass arguments in registers.
  560. X *
  561. X *    Note that the default define allows up to 16 integral arguments,
  562. X *    or 8 floating point arguments (doubles), on most machines.
  563. X *
  564. X *    Someday this may be replaced with true varargs support, when
  565. X *    ANSI C has had time to take root.
  566. X */
  567. X
  568. X#define ARGLIST a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15
  569. X
  570. X/*
  571. X * The default file for profiling.  Could also add another flag
  572. X * (G?) which allowed the user to specify this.
  573. X */
  574. X
  575. X#define PROF_FILE    "dbugmon.out"
  576. X
  577. X/*
  578. X *    Variables which are available externally but should only
  579. X *    be accessed via the macro package facilities.
  580. X */
  581. X
  582. XEXPORT FILE *_db_fp_ = stderr;        /* Output stream, default stderr */
  583. XEXPORT FILE *_db_pfp_ = (FILE *)0;    /* Profile stream, 'dbugmon.out' */
  584. XEXPORT char *_db_process_ = "dbug";    /* Pointer to process name; argv[0] */
  585. XEXPORT BOOLEAN _db_on_ = FALSE;        /* TRUE if debugging currently on */
  586. XEXPORT BOOLEAN _db_pon_ = FALSE;    /* TRUE if debugging currently on */
  587. X
  588. X/*
  589. X *    Externally supplied functions.
  590. X */
  591. X
  592. X#ifdef unix            /* Only needed for unix */
  593. XIMPORT VOID perror ();        /* Print system/library error */
  594. XIMPORT int chown ();        /* Change owner of a file */
  595. XIMPORT int getgid ();        /* Get real group id */
  596. XIMPORT int getuid ();        /* Get real user id */
  597. XIMPORT int access ();        /* Test file for access */
  598. X#else
  599. X#if !(AMIGA && LATTICE)
  600. XLOCAL VOID perror ();        /* Fake system/library error print routine */
  601. X#endif
  602. X#endif
  603. X
  604. X# if BSD4_3 || sun
  605. XIMPORT int getrusage ();
  606. X#endif
  607. X
  608. XIMPORT int atoi ();        /* Convert ascii to integer */
  609. XIMPORT VOID exit ();        /* Terminate execution */
  610. XIMPORT int fclose ();        /* Close a stream */
  611. XIMPORT FILE *fopen ();        /* Open a stream */
  612. XIMPORT int fprintf ();        /* Formatted print on file */
  613. XIMPORT VOID free ();
  614. XIMPORT char *malloc ();        /* Allocate memory */
  615. XIMPORT int strcmp ();        /* Compare strings */
  616. XIMPORT char *strcpy ();        /* Copy strings around */
  617. XIMPORT int strlen ();        /* Find length of string */
  618. X
  619. X#ifndef fflush            /* This is sometimes a macro */
  620. XIMPORT int fflush ();        /* Flush output for stream */
  621. X#endif
  622. X
  623. X
  624. X/*
  625. X *    The user may specify a list of functions to trace or 
  626. X *    debug.  These lists are kept in a linear linked list,
  627. X *    a very simple implementation.
  628. X */
  629. X
  630. Xstruct link {
  631. X    char *string;        /* Pointer to link's contents */
  632. X    struct link *next_link;    /* Pointer to the next link */
  633. X};
  634. X
  635. X
  636. X/*
  637. X *    Debugging states can be pushed or popped off of a
  638. X *    stack which is implemented as a linked list.  Note
  639. X *    that the head of the list is the current state and the
  640. X *    stack is pushed by adding a new state to the head of the
  641. X *    list or popped by removing the first link.
  642. X */
  643. X
  644. Xstruct state {
  645. X    int flags;                /* Current state flags */
  646. X    int maxdepth;            /* Current maximum trace depth */
  647. X    unsigned int delay;            /* Delay after each output line */
  648. X    int level;                /* Current function nesting level */
  649. X    FILE *out_file;            /* Current output stream */
  650. X    FILE *prof_file;            /* Current profiling stream */
  651. X    struct link *functions;        /* List of functions */
  652. X    struct link *p_functions;        /* List of profiled functions */
  653. X    struct link *keywords;        /* List of debug keywords */
  654. X    struct link *processes;        /* List of process names */
  655. X    struct state *next_state;        /* Next state in the list */
  656. X};
  657. X
  658. XLOCAL struct state *stack = NULL;    /* Linked list of stacked states */
  659. X
  660. X/*
  661. X *    Local variables not seen by user.
  662. X */
  663. X
  664. XLOCAL int lineno = 0;        /* Current debugger output line number */
  665. XLOCAL char *func = "?func";    /* Name of current user function */
  666. XLOCAL char *file = "?file";    /* Name of current user file */
  667. XLOCAL BOOLEAN init_done = FALSE;/* Set to TRUE when initialization done */
  668. X
  669. X/*#if unix || AMIGA || M_I86*/
  670. XLOCAL int jmplevel;        /* Remember nesting level at setjmp () */
  671. XLOCAL char *jmpfunc;        /* Remember current function for setjmp */
  672. XLOCAL char *jmpfile;        /* Remember current file for setjmp */
  673. X/*#endif*/
  674. X
  675. XLOCAL struct link *ListParse ();/* Parse a debug command string */
  676. XLOCAL char *StrDup ();        /* Make a fresh copy of a string */
  677. XLOCAL VOID OpenFile ();        /* Open debug output stream */
  678. XLOCAL VOID OpenProfile ();    /* Open profile output stream */
  679. XLOCAL VOID CloseFile ();    /* Close debug output stream */
  680. XLOCAL VOID PushState ();    /* Push current debug state */
  681. XLOCAL VOID ChangeOwner ();    /* Change file owner and group */
  682. XLOCAL BOOLEAN DoTrace ();    /* Test for tracing enabled */
  683. XLOCAL BOOLEAN Writable ();    /* Test to see if file is writable */
  684. XLOCAL unsigned long Clock ();    /* Return current user time (ms) */
  685. XLOCAL char *DbugMalloc ();    /* Allocate memory for runtime support */
  686. XLOCAL char *BaseName ();    /* Remove leading pathname components */
  687. XLOCAL VOID DoPrefix ();        /* Print debugger line prefix */
  688. XLOCAL VOID FreeList ();        /* Free memory from linked list */
  689. XLOCAL VOID Indent ();        /* Indent line to specified indent */
  690. X
  691. X                /* Supplied in Sys V runtime environ */
  692. XLOCAL char *strtok ();        /* Break string into tokens */
  693. XLOCAL char *strrchr ();        /* Find last occurance of char */
  694. X
  695. X/*
  696. X *    The following local variables are used to hold the state information
  697. X *    between the call to _db_pargs_() and _db_doprnt_(), during
  698. X *    expansion of the DBUG_PRINT macro.  This is the only macro
  699. X *    that currently uses these variables.  The DBUG_PRINT macro
  700. X *    and the new _db_doprnt_() routine replace the older DBUG_N macros
  701. X *    and their corresponding runtime support routine _db_printf_().
  702. X *
  703. X *    These variables are currently used only by _db_pargs_() and
  704. X *    _db_doprnt_().
  705. X */
  706. X
  707. XLOCAL int u_line = 0;        /* User source code line number */
  708. XLOCAL char *u_keyword = "?";    /* Keyword for current macro */
  709. X
  710. X/*
  711. X *    Miscellaneous printf format strings.
  712. X */
  713. X#define ERR_MISSING_RETURN "%s: missing DBUG_RETURN or DBUG_VOID_RETURN macro in function \"%s\"\n"
  714. X#define ERR_OPEN "%s: can't open debug output stream \"%s\": "
  715. X#define ERR_CLOSE "%s: can't close debug file: "
  716. X#define ERR_ABORT "%s: debugger aborting because %s\n"
  717. X#define ERR_CHOWN "%s: can't change owner/group of \"%s\": "
  718. X#define ERR_PRINTF "%s: obsolete object file for '%s', please recompile!\n"
  719. X
  720. X/*
  721. X *    Macros and defines for testing file accessibility under UNIX.
  722. X */
  723. X
  724. X#ifdef unix
  725. X#  define A_EXISTS    00        /* Test for file existance */
  726. X#  define A_EXECUTE    01        /* Test for execute permission */
  727. X#  define A_WRITE    02        /* Test for write access */
  728. X#  define A_READ    03        /* Test for read access */
  729. X#  define EXISTS(pathname) (access (pathname, A_EXISTS) == 0)
  730. X#  define WRITABLE(pathname) (access (pathname, A_WRITE) == 0)
  731. X#else
  732. X#  define EXISTS(pathname) (FALSE)    /* Assume no existance */
  733. X#endif
  734. X
  735. X/*
  736. X *    Translate some calls among different systems.
  737. X */
  738. X
  739. X#ifdef unix
  740. X# define XDelay sleep
  741. XIMPORT unsigned int sleep ();    /* Pause for given number of seconds */
  742. X#endif
  743. X
  744. X#ifdef AMIGA
  745. XIMPORT int XDelay ();        /* Pause for given number of ticks */
  746. X#endif
  747. X
  748. X
  749. X/*
  750. X *  FUNCTION
  751. X *
  752. X *    _db_push_    push current debugger state and set up new one
  753. X *
  754. X *  SYNOPSIS
  755. X *
  756. X *    VOID _db_push_ (control)
  757. X *    char *control;
  758. X *
  759. X *  DESCRIPTION
  760. X *
  761. X *    Given pointer to a debug control string in "control", pushes
  762. X *    the current debug state, parses the control string, and sets
  763. X *    up a new debug state.
  764. X *
  765. X *    The only attribute of the new state inherited from the previous
  766. X *    state is the current function nesting level.  This can be
  767. X *    overridden by using the "r" flag in the control string.
  768. X *
  769. X *    The debug control string is a sequence of colon separated fields
  770. X *    as follows:
  771. X *
  772. X *        <field_1>:<field_2>:...:<field_N>
  773. X *
  774. X *    Each field consists of a mandatory flag character followed by
  775. X *    an optional "," and comma separated list of modifiers:
  776. X *
  777. X *        flag[,modifier,modifier,...,modifier]
  778. X *
  779. X *    The currently recognized flag characters are:
  780. X *
  781. X *        d    Enable output from DBUG_<N> macros for
  782. X *            for the current state.  May be followed
  783. X *            by a list of keywords which selects output
  784. X *            only for the DBUG macros with that keyword.
  785. X *            A null list of keywords implies output for
  786. X *            all macros.
  787. X *
  788. X *        D    Delay after each debugger output line.
  789. X *            The argument is the number of tenths of seconds
  790. X *            to delay, subject to machine capabilities.
  791. X *            I.E.  -#D,20 is delay two seconds.
  792. X *
  793. X *        f    Limit debugging and/or tracing, and profiling to the
  794. X *            list of named functions.  Note that a null list will
  795. X *            disable all functions.  The appropriate "d" or "t"
  796. X *            flags must still be given, this flag only limits their
  797. X *            actions if they are enabled.
  798. X *
  799. X *        F    Identify the source file name for each
  800. X *            line of debug or trace output.
  801. X *
  802. X *        g    Enable profiling.  Create a file called 'dbugmon.out'
  803. X *            containing information that can be used to profile
  804. X *            the program.  May be followed by a list of keywords
  805. X *            that select profiling only for the functions in that
  806. X *            list.  A null list implies that all functions are
  807. X *            considered.
  808. X *
  809. X *        L    Identify the source file line number for
  810. X *            each line of debug or trace output.
  811. X *
  812. X *        n    Print the current function nesting depth for
  813. X *            each line of debug or trace output.
  814. X *    
  815. X *        N    Number each line of dbug output.
  816. X *
  817. X *        p    Limit debugger actions to specified processes.
  818. X *            A process must be identified with the
  819. X *            DBUG_PROCESS macro and match one in the list
  820. X *            for debugger actions to occur.
  821. X *
  822. X *        P    Print the current process name for each
  823. X *            line of debug or trace output.
  824. X *
  825. X *        r    When pushing a new state, do not inherit
  826. X *            the previous state's function nesting level.
  827. X *            Useful when the output is to start at the
  828. X *            left margin.
  829. X *
  830. X *        t    Enable function call/exit trace lines.
  831. X *            May be followed by a list (containing only
  832. X *            one modifier) giving a numeric maximum
  833. X *            trace level, beyond which no output will
  834. X *            occur for either debugging or tracing
  835. X *            macros.  The default is a compile time
  836. X *            option.
  837. X *
  838. X *    Some examples of debug control strings which might appear
  839. X *    on a shell command line (the "-#" is typically used to
  840. X *    introduce a control string to an application program) are:
  841. X *
  842. X *        -#d:t
  843. X *        -#d:f,main,subr1:F:L:t,20
  844. X *        -#d,input,output,files:n
  845. X *
  846. X *    For convenience, any leading "-#" is stripped off.
  847. X *
  848. X */
  849. X
  850. X
  851. XVOID _db_push_ (control)
  852. Xchar *control;
  853. X{
  854. X    REGISTER char *scan;
  855. X    REGISTER struct link *temp;
  856. X
  857. X    if (control && *control == '-') {
  858. X    if (*++control == '#') {
  859. X        control++;
  860. X    }    
  861. X    }
  862. X    control = StrDup (control);
  863. X    PushState ();
  864. X    scan = strtok (control, ":");
  865. X    for (; scan != NULL; scan = strtok ((char *)NULL, ":")) {
  866. X    switch (*scan++) {
  867. X        case 'd': 
  868. X        _db_on_ = TRUE;
  869. X        stack -> flags |= DEBUG_ON;
  870. X        if (*scan++ == ',') {
  871. X            stack -> keywords = ListParse (scan);
  872. X        }
  873. X            break;
  874. X        case 'D': 
  875. X        stack -> delay = 0;
  876. X        if (*scan++ == ',') {
  877. X            temp = ListParse (scan);
  878. X            stack -> delay = DelayArg (atoi (temp -> string));
  879. X            FreeList (temp);
  880. X        }
  881. X        break;
  882. X        case 'f': 
  883. X        if (*scan++ == ',') {
  884. X            stack -> functions = ListParse (scan);
  885. X        }
  886. X        break;
  887. X        case 'F': 
  888. X        stack -> flags |= FILE_ON;
  889. X        break;
  890. X        case 'g': 
  891. X        _db_pon_ = TRUE;
  892. X        OpenProfile(PROF_FILE);
  893. X        stack -> flags |= PROFILE_ON;
  894. X        if (*scan++ == ',') {
  895. X            stack -> p_functions = ListParse (scan);
  896. X        }
  897. X        break;
  898. X        case 'L': 
  899. X        stack -> flags |= LINE_ON;
  900. X        break;
  901. X        case 'n': 
  902. X        stack -> flags |= DEPTH_ON;
  903. X        break;
  904. X        case 'N':
  905. X        stack -> flags |= NUMBER_ON;
  906. X        break;
  907. X        case 'o': 
  908. X        if (*scan++ == ',') {
  909. X            temp = ListParse (scan);
  910. X            OpenFile (temp -> string);
  911. X            FreeList (temp);
  912. X        } else {
  913. X            OpenFile ("-");
  914. X        }
  915. X        break;
  916. X        case 'p':
  917. X        if (*scan++ == ',') {
  918. X            stack -> processes = ListParse (scan);
  919. X        }
  920. X        break;
  921. X        case 'P': 
  922. X        stack -> flags |= PROCESS_ON;
  923. X        break;
  924. X        case 'r': 
  925. X        stack -> level = 0;
  926. X        break;
  927. X        case 't': 
  928. X        stack -> flags |= TRACE_ON;
  929. X        if (*scan++ == ',') {
  930. X            temp = ListParse (scan);
  931. X            stack -> maxdepth = atoi (temp -> string);
  932. X            FreeList (temp);
  933. X        }
  934. X        break;
  935. X    }
  936. X    }
  937. X    free (control);
  938. X}
  939. X
  940. X
  941. X
  942. X/*
  943. X *  FUNCTION
  944. X *
  945. X *    _db_pop_    pop the debug stack
  946. X *
  947. X *  DESCRIPTION
  948. X *
  949. X *    Pops the debug stack, returning the debug state to its
  950. X *    condition prior to the most recent _db_push_ invocation.
  951. X *    Note that the pop will fail if it would remove the last
  952. X *    valid state from the stack.  This prevents user errors
  953. X *    in the push/pop sequence from screwing up the debugger.
  954. X *    Maybe there should be some kind of warning printed if the
  955. X *    user tries to pop too many states.
  956. X *
  957. X */
  958. X
  959. XVOID _db_pop_ ()
  960. X{
  961. X    REGISTER struct state *discard;
  962. X
  963. X    discard = stack;
  964. X    if (discard != NULL && discard -> next_state != NULL) {
  965. X    stack = discard -> next_state;
  966. X    _db_fp_ = stack -> out_file;
  967. X    _db_pfp_ = stack -> prof_file;
  968. X    if (discard -> keywords != NULL) {
  969. X        FreeList (discard -> keywords);
  970. X    }
  971. X    if (discard -> functions != NULL) {
  972. X        FreeList (discard -> functions);
  973. X    }
  974. X    if (discard -> processes != NULL) {
  975. X        FreeList (discard -> processes);
  976. X    }
  977. X    if (discard -> p_functions != NULL) {
  978. X        FreeList (discard -> p_functions);
  979. X    }
  980. X    CloseFile (discard -> out_file);
  981. X    CloseFile (discard -> prof_file);
  982. X    free ((char *) discard);
  983. X    }
  984. X}
  985. X
  986. X
  987. X/*
  988. X *  FUNCTION
  989. X *
  990. X *    _db_enter_    process entry point to user function
  991. X *
  992. X *  SYNOPSIS
  993. X *
  994. X *    VOID _db_enter_ (_func_, _file_, _line_, _sfunc_, _sfile_, _slevel_)
  995. X *    char *_func_;        points to current function name
  996. X *    char *_file_;        points to current file name
  997. X *    int _line_;        called from source line number
  998. X *    char **_sfunc_;        save previous _func_
  999. X *    char **_sfile_;        save previous _file_
  1000. X *    int *_slevel_;        save previous nesting level
  1001. X *
  1002. X *  DESCRIPTION
  1003. X *
  1004. X *    Called at the beginning of each user function to tell
  1005. X *    the debugger that a new function has been entered.
  1006. X *    Note that the pointers to the previous user function
  1007. X *    name and previous user file name are stored on the
  1008. X *    caller's stack (this is why the ENTER macro must be
  1009. X *    the first "executable" code in a function, since it
  1010. X *    allocates these storage locations).  The previous nesting
  1011. X *    level is also stored on the callers stack for internal
  1012. X *    self consistency checks.
  1013. X *
  1014. X *    Also prints a trace line if tracing is enabled and
  1015. X *    increments the current function nesting depth.
  1016. X *
  1017. X *    Note that this mechanism allows the debugger to know
  1018. X *    what the current user function is at all times, without
  1019. X *    maintaining an internal stack for the function names.
  1020. X *
  1021. X */
  1022. X
  1023. XVOID _db_enter_ (_func_, _file_, _line_, _sfunc_, _sfile_, _slevel_)
  1024. Xchar *_func_;
  1025. Xchar *_file_;
  1026. Xint _line_;
  1027. Xchar **_sfunc_;
  1028. Xchar **_sfile_;
  1029. Xint *_slevel_;
  1030. X{
  1031. X    if (!init_done) {
  1032. X    _db_push_ ("");
  1033. X    }
  1034. X    *_sfunc_ = func;
  1035. X    *_sfile_ = file;
  1036. X    func = _func_;
  1037. X    file = BaseName (_file_);
  1038. X    stack -> level++;
  1039. X    *_slevel_ = stack -> level;
  1040. X    if (DoProfile ()) {
  1041. X    (VOID) fprintf (_db_pfp_, "%s\tE\t%ld\n",func, Clock());
  1042. X    (VOID) fflush (_db_pfp_);
  1043. X    }
  1044. X    if (DoTrace ()) {
  1045. X    DoPrefix (_line_);
  1046. X    Indent (stack -> level);
  1047. X    (VOID) fprintf (_db_fp_, ">%s\n", func);
  1048. X    (VOID) fflush (_db_fp_);
  1049. X    (VOID) XDelay (stack -> delay);
  1050. X    }
  1051. X}
  1052. X
  1053. X
  1054. X/*
  1055. X *  FUNCTION
  1056. X *
  1057. X *    _db_return_    process exit from user function
  1058. X *
  1059. X *  SYNOPSIS
  1060. X *
  1061. X *    VOID _db_return_ (_line_, _sfunc_, _sfile_, _slevel_)
  1062. X *    int _line_;        current source line number
  1063. X *    char **_sfunc_;        where previous _func_ is to be retrieved
  1064. X *    char **_sfile_;        where previous _file_ is to be retrieved
  1065. X *    int *_slevel_;        where previous level was stashed
  1066. X *
  1067. X *  DESCRIPTION
  1068. X *
  1069. X *    Called just before user function executes an explicit or implicit
  1070. X *    return.  Prints a trace line if trace is enabled, decrements
  1071. X *    the current nesting level, and restores the current function and
  1072. X *    file names from the defunct function's stack.
  1073. X *
  1074. X */
  1075. X
  1076. XVOID _db_return_ (_line_, _sfunc_, _sfile_, _slevel_)
  1077. Xint _line_;
  1078. Xchar **_sfunc_;
  1079. Xchar **_sfile_;
  1080. Xint *_slevel_;
  1081. X{
  1082. X    if (!init_done) {
  1083. X    _db_push_ ("");
  1084. X    }
  1085. X    if (stack -> level != *_slevel_ && (TRACING || DEBUGGING || PROFILING)) {
  1086. X    (VOID) fprintf (_db_fp_, ERR_MISSING_RETURN, _db_process_, func);
  1087. X        (VOID) XDelay (stack -> delay);
  1088. X    } else if (DoProfile ()) {
  1089. X    (VOID) fprintf (_db_pfp_, "%s\tX\t%ld\n", func, Clock());
  1090. X        (VOID) XDelay (stack -> delay);
  1091. X    } else if (DoTrace ()) {
  1092. X    DoPrefix (_line_);
  1093. X    Indent (stack -> level);
  1094. X    (VOID) fprintf (_db_fp_, "<%s\n", func);
  1095. X        (VOID) XDelay (stack -> delay);
  1096. X    }
  1097. X    (VOID) fflush (_db_fp_);
  1098. X    stack -> level = *_slevel_ - 1;
  1099. X    func = *_sfunc_;
  1100. X    file = *_sfile_;
  1101. X}
  1102. X
  1103. X
  1104. X/*
  1105. X *  FUNCTION
  1106. X *
  1107. X *    _db_pargs_    log arguments for subsequent use by _db_doprnt_()
  1108. X *
  1109. X *  SYNOPSIS
  1110. X *
  1111. X *    VOID _db_pargs_ (_line_, keyword)
  1112. X *    int _line_;
  1113. X *    char *keyword;
  1114. X *
  1115. X *  DESCRIPTION
  1116. X *
  1117. X *    The new universal printing macro DBUG_PRINT, which replaces
  1118. X *    all forms of the DBUG_N macros, needs two calls to runtime
  1119. X *    support routines.  The first, this function, remembers arguments
  1120. X *    that are used by the subsequent call to _db_doprnt_().
  1121. X*
  1122. X */
  1123. X
  1124. XVOID _db_pargs_ (_line_, keyword)
  1125. Xint _line_;
  1126. Xchar *keyword;
  1127. X{
  1128. X    u_line = _line_;
  1129. X    u_keyword = keyword;
  1130. X}
  1131. X
  1132. X
  1133. X/*
  1134. X *  FUNCTION
  1135. X *
  1136. X *    _db_doprnt_    handle print of debug lines
  1137. X *
  1138. X *  SYNOPSIS
  1139. X *
  1140. X *    VOID _db_doprnt_ (format, ARGLIST)
  1141. X *    char *format;
  1142. X *    long ARGLIST;
  1143. X *
  1144. X *  DESCRIPTION
  1145. X *
  1146. X *    When invoked via one of the DBUG macros, tests the current keyword
  1147. X *    set by calling _db_pargs_() to see if that macro has been selected
  1148. X *    for processing via the debugger control string, and if so, handles
  1149. X *    printing of the arguments via the format string.  The line number
  1150. X *    of the DBUG macro in the source is found in u_line.
  1151. X *
  1152. X *    Note that the format string SHOULD NOT include a terminating
  1153. X *    newline, this is supplied automatically.
  1154. X *
  1155. X *  NOTES
  1156. X *
  1157. X *    This runtime support routine replaces the older _db_printf_()
  1158. X *    routine which is temporarily kept around for compatibility.
  1159. X *
  1160. X *    The rather ugly argument declaration is to handle some
  1161. X *    magic with respect to the number of arguments passed
  1162. X *    via the DBUG macros.  The current maximum is 3 arguments
  1163. X *    (not including the keyword and format strings).
  1164. X *
  1165. X *    The new <varargs.h> facility is not yet common enough to
  1166. X *    convert to it quite yet...
  1167. X *
  1168. X */
  1169. X
  1170. X/*VARARGS1*/
  1171. XVOID _db_doprnt_ (format, ARGLIST)
  1172. Xchar *format;
  1173. Xlong ARGLIST;
  1174. X{
  1175. X    if (_db_keyword_ (u_keyword)) {
  1176. X    DoPrefix (u_line);
  1177. X    if (TRACING) {
  1178. X        Indent (stack -> level + 1);
  1179. X    } else {
  1180. X        (VOID) fprintf (_db_fp_, "%s: ", func);
  1181. X    }
  1182. X    (VOID) fprintf (_db_fp_, "%s: ", u_keyword);
  1183. X    (VOID) fprintf (_db_fp_, format, ARGLIST);
  1184. X    (VOID) fprintf (_db_fp_, "\n");
  1185. X    (VOID) fflush (_db_fp_);
  1186. X    (VOID) XDelay (stack -> delay);
  1187. X    }
  1188. X}
  1189. X
  1190. X/*
  1191. X *    The following routine is kept around temporarily for compatibility
  1192. X *    with older objects that were compiled with the DBUG_N macro form
  1193. X *    of the print routine.  It will print a warning message on first
  1194. X *    usage.  It will go away in subsequent releases...
  1195. X */
  1196. X
  1197. X/*VARARGS3*/
  1198. XVOID _db_printf_ (_line_, keyword, format, ARGLIST)
  1199. Xint _line_;
  1200. Xchar *keyword,  *format;
  1201. Xlong ARGLIST;
  1202. X{
  1203. X    static BOOLEAN firsttime = TRUE;
  1204. X
  1205. X    if (firsttime) {
  1206. X    (VOID) fprintf (stderr, ERR_PRINTF, _db_process_, file);
  1207. X    firsttime = FALSE;
  1208. X    }
  1209. X    _db_pargs_ (_line_, keyword);
  1210. X    _db_doprnt_ (format, ARGLIST);
  1211. X}
  1212. X
  1213. X
  1214. X/*
  1215. X *  FUNCTION
  1216. X *
  1217. X *    ListParse    parse list of modifiers in debug control string
  1218. X *
  1219. X *  SYNOPSIS
  1220. X *
  1221. X *    LOCAL struct link *ListParse (ctlp)
  1222. X *    char *ctlp;
  1223. X *
  1224. X *  DESCRIPTION
  1225. X *
  1226. X *    Given pointer to a comma separated list of strings in "cltp",
  1227. X *    parses the list, building a list and returning a pointer to it.
  1228. X *    The original comma separated list is destroyed in the process of
  1229. X *    building the linked list, thus it had better be a duplicate
  1230. X *    if it is important.
  1231. X *
  1232. X *    Note that since each link is added at the head of the list,
  1233. X *    the final list will be in "reverse order", which is not
  1234. X *    significant for our usage here.
  1235. X *
  1236. X */
  1237. X
  1238. XLOCAL struct link *ListParse (ctlp)
  1239. Xchar *ctlp;
  1240. X{
  1241. X    REGISTER char *start;
  1242. X    REGISTER struct link *new;
  1243. X    REGISTER struct link *head;
  1244. X
  1245. X    head = NULL;
  1246. SHAR_EOF
  1247. echo "End of part 19"
  1248. echo "File common/dbug.c is continued in part 20"
  1249. echo "20" > s2_seq_.tmp
  1250. exit 0
  1251.  
  1252.