home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / mar94 / util / misc / flush.lha / Flush / Flush.c < prev    next >
C/C++ Source or Header  |  1994-01-13  |  16KB  |  820 lines

  1.  
  2. #define VERSION "1.2"
  3.  
  4. /*********************************************************************
  5.  
  6.  * Flush        Flushes all unused libraries, devices and fonts.
  7.  *              Note that some libraries and devices refuse to
  8.  *              flush themselves.
  9.  *
  10.  *
  11.  * Options:
  12.  *
  13.  *      -d    ; only flush devices
  14.  *      -f    ; only flush fonts
  15.  *      -l    ; only flush libraries
  16.  *      -r    ; report only; don't flush
  17.  *      -v    ; be verbose; print names of all removed objects
  18.  *      -oOBJ ; remove OBJ , must have a suffix of
  19.  *                         .library, .device, or .font(x,y)
  20.  *      -h    ; this message
  21.  *
  22.  *
  23.  * Runs under AmigaDOS 2.04+
  24.  *
  25.  *
  26.  *****  Written by Gary Duncan
  27.  *
  28.  *      Bug reports etc via e-mail to gduncan@philips.oz.au) , or mail to
  29.  *
  30.  *Work: Gary Duncan
  31.  *      Philips PTS
  32.  *      23 Lakeside Dr
  33.  *      Tally-Ho Technology Park
  34.  *      Burwood East Vic 3151
  35.  *      Australia
  36.  *
  37.  *Home: Gary Duncan
  38.  *      57 Melbourne Hill Rd
  39.  *      Warrandyte
  40.  *      Vic 3113
  41.  *      Australia
  42.  *
  43.  *Thanks to these beta-testers for testing early versions:-
  44.  *
  45.  *      Benbuck Nason (bigben@netcom.com)
  46.  *      Torsten Nielsen (torsten@diku.dk)
  47.  *      Darren Reid and others (shockwave@jupiter.sun.csd.unb.ca)
  48.  *
  49.  *
  50.  *****  Freely distributable for non-commercial purposes.
  51.  *      Please keep this header intact.
  52.  *
  53.  *      Use this program at your own risk.
  54.  *
  55.  *
  56.  *      Compiles under SAS 6.3
  57.  *
  58.  *      Formatted with 'indent -gnu' ; a big time-saving program.
  59.  *
  60.  *****************************************************************/
  61.  
  62. #include "flush.h"
  63.  
  64. extern struct GfxBase *GfxBase;
  65.  
  66.  
  67. /*
  68.  * string for AmigaDOS Version Command
  69.  */
  70. char A_vers[] = "\0$VER: Flush\t" VERSION " (13.1.94)";
  71.  
  72.  
  73. /*
  74.  * lib/device array ; one entry per lib/device list containing
  75.  * name and open count.
  76.  */
  77.  
  78. static S_LIB *pre_flush;
  79. static S_LIB *post_flush;
  80.  
  81. static int pre_cnt = 0;
  82. static int post_cnt = 0;
  83.  
  84. char *remove_it;
  85.  
  86. int r_count = 0;
  87.  
  88. ULONG s_total;
  89. ULONG s_fast;
  90. ULONG s_chipx;
  91.  
  92. ULONG e_total;
  93. ULONG e_fast;
  94. ULONG e_chipx;
  95.  
  96. ULONG r_total;
  97. ULONG r_fast;
  98. ULONG r_chipx;
  99.  
  100. BOOL v_flag = FALSE;
  101. BOOL r_flag = FALSE;
  102. BOOL o_flag = FALSE;
  103. BOOL d_flag = FALSE;
  104. BOOL f_flag = FALSE;
  105. BOOL l_flag = FALSE;
  106.  
  107. /*
  108.  **********************************************************
  109.  */
  110.  
  111. main (int argc, char **argv)
  112.  
  113. {
  114.   ULONG t, c, f;
  115.  
  116.   /*
  117.    * check options
  118.    */
  119.  
  120.   scan_args (argc, argv);
  121.  
  122.   /*
  123.    * get buffers to hold List items
  124.    */
  125.  
  126.   GetItemsBuf (&pre_flush, &post_flush);
  127.  
  128.   /*
  129.    * kluge to get printf() to get its 16K malloc'd buffer now
  130.    * so that it won't confuse memory usage reporting later
  131.    */
  132.  
  133.   printf ("\r");
  134.   fflush (stdout);
  135.  
  136.   /*
  137.    * get memory at start
  138.    */
  139.   memm (&s_fast, &s_chipx);
  140.  
  141.   /*
  142.    * check if its just one removal
  143.    */
  144.   if (o_flag)
  145.     {
  146.       rem_obj (remove_it);
  147.     }
  148.   else
  149.     {
  150.       /*
  151.        * flush fonts before libs, as attempting to flush
  152.        * diskfont.library seems to flush them automatically
  153.        * and we want font flushing shown.
  154.        */
  155.       if (f_flag == TRUE)
  156.     {
  157.       FlushFonts (r_flag);
  158.     }
  159.       else if (l_flag == TRUE)
  160.     {
  161.       FlushLibraries (r_flag);
  162.     }
  163.       else if (d_flag == TRUE)
  164.     {
  165.       FlushDevices (r_flag);
  166.     }
  167.       else
  168.     {
  169.       FlushFonts (r_flag);
  170.       FlushLibraries (r_flag);
  171.       FlushDevices (r_flag);
  172.     }
  173.     }
  174.   /*
  175.    * get memory at end
  176.    */
  177.   memm (&e_fast, &e_chipx);
  178.  
  179.   c = (e_chipx - s_chipx) / 1024;
  180.   f = (e_fast - s_fast) / 1024;
  181.   t = c + f;
  182.  
  183.   if (r_flag == FALSE)
  184.     {
  185.       printf ("Memory regained (KB) : total = %ld, [chip = %ld, fast = %ld]\n",
  186.           t, c, f);
  187.     }
  188. }
  189.  
  190. /*
  191.  **********************************************************
  192.  */
  193.  
  194. void
  195. FlushLibraries (BOOL flag)
  196. {
  197.   LIBRARY *l_ptr;
  198.   NODE *node;
  199.   int lib_cnt = 0;
  200.   int open_cnt = 0;
  201.   int j;
  202.   int cc = 0;
  203.   BOOL flushed_flag;
  204.  
  205.  
  206.   pre_cnt = 0;
  207.   post_cnt = 0;
  208.  
  209.   /*
  210.    * iterate through lib list until all flushable libs flushed;
  211.    * need to do this because some libs use other libs, i.e do
  212.    * a flush themselves
  213.    *
  214.    * - if "report" option, just pass through once
  215.    *
  216.    */
  217.  
  218.   while (TRUE)
  219.     {
  220.       Forbid ();
  221.       for (flushed_flag = FALSE, node = SysBase->LibList.lh_Head;
  222.        node->ln_Succ; node = node->ln_Succ)
  223.     {
  224.       char *l_name;
  225.       ++cc;
  226.       l_ptr = (LIBRARY *) node;
  227.       l_name = node->ln_Name;
  228.  
  229.       open_cnt = l_ptr->lib_OpenCnt;
  230.  
  231.       /*
  232.        * if flushable, record if not already in table
  233.        */
  234.       if (
  235.            (open_cnt == 0)
  236.            &&
  237.            (!check_flushed (pre_cnt, pre_flush, l_name))
  238.         )
  239.  
  240.         {
  241.           /*
  242.            * hold open count, lib name
  243.            */
  244.           pre_flush[pre_cnt].o_cnt = open_cnt;
  245.           pre_flush[pre_cnt].confeds.vr.ver = l_ptr->lib_Version;
  246.           pre_flush[pre_cnt].confeds.vr.rev = l_ptr->lib_Revision;
  247.  
  248.           strncpy (pre_flush[pre_cnt].name, l_name, S_BUFLEN - 1);
  249.           /*
  250.            * don't flush diskfont.library if fonts shouldn't be
  251.            * flushed
  252.            */
  253.           if (r_flag == FALSE)
  254.         {
  255.           if (!(l_flag && (strcmp (l_name, "diskfont.library") == 0)))
  256.             RemLibrary (l_ptr);
  257.         }
  258.           flushed_flag = TRUE;
  259.           ++pre_cnt;
  260.         }
  261.     }
  262.       Permit ();
  263.  
  264.       if (lib_cnt == 0)
  265.     lib_cnt = cc;        /* hold first pass lib count */
  266.       /*
  267.        * if no flushable libs this time, exit loop
  268.        */
  269.       if ((flushed_flag == FALSE) || (r_flag == TRUE))
  270.     break;
  271.     }
  272.   /*
  273.    * see if report only
  274.    */
  275.   if (r_flag == TRUE)
  276.     {
  277.       for (j = 0; j < pre_cnt; ++j)
  278.     {
  279.       char *l_name = pre_flush[j].name;
  280.  
  281.       printf ("\tFlushable Library      :  %-27s(%d.%d)\n", l_name,
  282.           pre_flush[j].confeds.vr.ver,
  283.           pre_flush[j].confeds.vr.rev);
  284.     }
  285.       return;
  286.     }
  287.  
  288.   /*
  289.    * now see what's been flushed
  290.    */
  291.   if (pre_cnt)
  292.     {
  293.       Forbid ();
  294.       for (node = SysBase->LibList.lh_Head; node->ln_Succ;
  295.        node = node->ln_Succ)
  296.     {
  297.       l_ptr = (LIBRARY *) node;
  298.       if (l_ptr->lib_OpenCnt == 0)
  299.         {
  300.           /*
  301.            * hold open count, lib name
  302.            */
  303.           post_flush[post_cnt].o_cnt = l_ptr->lib_OpenCnt;
  304.           post_flush[post_cnt].confeds.vr.ver = l_ptr->lib_Version;
  305.           post_flush[post_cnt].confeds.vr.rev = l_ptr->lib_Revision;
  306.           strncpy (post_flush[post_cnt].name, node->ln_Name, S_BUFLEN - 1);
  307.  
  308.           ++post_cnt;
  309.         }
  310.     }
  311.       Permit ();
  312.     }
  313.   /*
  314.    * report on flushed libraries
  315.    */
  316.  
  317.   printf ("Libraries: total = %2d , flushable = %2d, flushed = %2d\n",
  318.       lib_cnt, pre_cnt, pre_cnt - post_cnt);
  319.   /*
  320.    * now see how many libraries flushed themselves
  321.    */
  322.  
  323.   if (pre_cnt && v_flag)
  324.     {
  325.       for (j = 0; j < pre_cnt; ++j)
  326.     {
  327.       char *l_name = pre_flush[j].name;
  328.  
  329.       if (!check_flushed (post_cnt, post_flush, l_name))
  330.         printf ("\tFlushed         :  %-27s(%d.%d)\n", l_name,
  331.             pre_flush[j].confeds.vr.ver,
  332.             pre_flush[j].confeds.vr.rev);
  333.     }
  334.       /*
  335.        * now see how many libraries did not flush themselves
  336.        */
  337.  
  338.       for (j = 0; j < post_cnt; ++j)
  339.     {
  340.       char *l_name = post_flush[j].name;
  341.  
  342.       printf ("\tNot Flushed     :  %-27s(%d.%d)\n", l_name,
  343.           post_flush[j].confeds.vr.ver,
  344.           post_flush[j].confeds.vr.rev);
  345.     }
  346.  
  347.       printf ("\n");
  348.     }
  349.   return;
  350. }
  351.  
  352. /*
  353.  **********************************************************
  354.  */
  355.  
  356. void
  357. FlushDevices (BOOL flag)
  358. {
  359.   LIBRARY *l_ptr;
  360.   NODE *node;
  361.   int dev_cnt = 0;
  362.   int j;
  363.  
  364.   pre_cnt = 0;
  365.   post_cnt = 0;
  366.  
  367.   Forbid ();
  368.   for (node = SysBase->DeviceList.lh_Head; node->ln_Succ;
  369.        node = node->ln_Succ)
  370.     {
  371.       l_ptr = (LIBRARY *) node;
  372.  
  373.       ++dev_cnt;
  374.       /*
  375.        * record all flushable (  open count  = 0 )
  376.        */
  377.  
  378.       if (l_ptr->lib_OpenCnt == 0)
  379.     {
  380.       /*
  381.        * hold open count, lib name
  382.        */
  383.       pre_flush[pre_cnt].o_cnt = l_ptr->lib_OpenCnt;
  384.       pre_flush[pre_cnt].confeds.vr.ver = l_ptr->lib_Version;
  385.       pre_flush[pre_cnt].confeds.vr.rev = l_ptr->lib_Revision;
  386.       strncpy (pre_flush[pre_cnt].name, node->ln_Name, S_BUFLEN);
  387.  
  388.       ++pre_cnt;
  389.  
  390.       if (r_flag == FALSE)
  391.         {
  392.           RemDevice ((DEVICE *) l_ptr);
  393.         }
  394.     }
  395.     }
  396.   Permit ();
  397.  
  398.   /*
  399.    * see if report only
  400.    */
  401.   if (r_flag == TRUE)
  402.     {
  403.       for (j = 0; j < pre_cnt; ++j)
  404.     {
  405.       char *l_name = pre_flush[j].name;
  406.  
  407.       printf ("\tFlushable Device       :  %-27s(%d.%d)\n", l_name,
  408.           pre_flush[j].confeds.vr.ver,
  409.           pre_flush[j].confeds.vr.rev);
  410.     }
  411.       return;
  412.     }
  413.   /*
  414.    * now see what's been flushed
  415.    */
  416.   if (pre_cnt)
  417.     {
  418.       Forbid ();
  419.       for (node = SysBase->DeviceList.lh_Head; node->ln_Succ;
  420.        node = node->ln_Succ)
  421.     {
  422.       l_ptr = (LIBRARY *) node;
  423.       if (l_ptr->lib_OpenCnt == 0)
  424.         {
  425.           /*
  426.            * hold open count, lib name
  427.            */
  428.           post_flush[post_cnt].o_cnt = l_ptr->lib_OpenCnt;
  429.           post_flush[post_cnt].confeds.vr.ver = l_ptr->lib_Version;
  430.           post_flush[post_cnt].confeds.vr.rev = l_ptr->lib_Revision;
  431.           strncpy (post_flush[post_cnt].name, node->ln_Name, S_BUFLEN);
  432.  
  433.           ++post_cnt;
  434.         }
  435.     }
  436.       Permit ();
  437.     }
  438.   /*
  439.    * report
  440.    */
  441.   printf ("Devices  : total = %2d , flushable = %2d, flushed = %2d\n",
  442.       dev_cnt, pre_cnt, pre_cnt - post_cnt);
  443.  
  444.   /*
  445.    * now see how many devices flushed themselves
  446.    */
  447.   if (pre_cnt && v_flag)
  448.     {
  449.       for (j = 0; j < pre_cnt; ++j)
  450.     {
  451.       char *l_name = pre_flush[j].name;
  452.  
  453.       if (!check_flushed (post_cnt, post_flush, l_name))
  454.         printf ("\tFlushed         :  %-27s(%d.%d)\n", l_name,
  455.             pre_flush[j].confeds.vr.ver,
  456.             pre_flush[j].confeds.vr.rev);
  457.     }
  458.       /*
  459.        * now see how many devices did not flush themselves
  460.        */
  461.  
  462.       for (j = 0; j < post_cnt; ++j)
  463.     {
  464.       char *l_name = post_flush[j].name;
  465.  
  466.       printf ("\tNot Flushed     :  %-27s(%d.%d)\n", l_name,
  467.           post_flush[j].confeds.vr.ver,
  468.           post_flush[j].confeds.vr.rev);
  469.     }
  470.       printf ("\n");
  471.     }
  472.   return;
  473. }
  474.  
  475. /*
  476.  **********************************************************
  477.  */
  478.  
  479. void
  480. FlushFonts (BOOL flag)
  481. {
  482.   TEXTFONT *tf;
  483.   NODE *node;
  484.   int font_cnt = 0;
  485.   int o_cnt;
  486.   int j;
  487.  
  488.   pre_cnt = 0;
  489.  
  490.   /*
  491.    * now record fonts, and flush those flushable
  492.    */
  493.  
  494.   Forbid ();
  495.   for (node = GfxBase->TextFonts.lh_Head; node->ln_Succ;
  496.        node = node->ln_Succ)
  497.     {
  498.       tf = (TEXTFONT *) node;
  499.  
  500.       ++font_cnt;
  501.  
  502.       o_cnt = tf->tf_Accessors;
  503.  
  504.       if ((o_cnt == 0) && (tf->tf_Flags & FPF_DISKFONT))
  505.     {
  506.       /*
  507.        * flushable ; hold  font name
  508.        */
  509.       pre_flush[pre_cnt].o_cnt = o_cnt;
  510.       pre_flush[pre_cnt].confeds.fonts.font_x = tf->tf_XSize;
  511.       pre_flush[pre_cnt].confeds.fonts.font_y = tf->tf_YSize;
  512.       strncpy (pre_flush[pre_cnt].name, node->ln_Name, S_BUFLEN - 1);
  513.  
  514.       ++pre_cnt;
  515.  
  516.       /*
  517.        * then flush it
  518.        */
  519.       if (r_flag == FALSE)
  520.         {
  521.           RemFont (tf);
  522.           Remove (node);
  523.         }
  524.     }
  525.     }
  526.   Permit ();
  527.  
  528.   /*
  529.    * see if report only
  530.    */
  531.   if (r_flag == TRUE)
  532.     {
  533.       for (j = 0; j < pre_cnt; ++j)
  534.     {
  535.       char *l_name = pre_flush[j].name;
  536.  
  537.       printf ("\tFlushable Font         :  %-27s(X=%2d,Y=%2d)\n", l_name,
  538.           pre_flush[j].confeds.fonts.font_x,
  539.           pre_flush[j].confeds.fonts.font_y);
  540.     }
  541.  
  542.       return;
  543.     }
  544.   /*
  545.    * see what's been flushed
  546.    */
  547.  
  548.   /*
  549.    * force font flushing (lib won't be flushed)
  550.    */
  551.   rem_obj ("diskfont.library");
  552.  
  553.   post_cnt = 0;
  554.  
  555.   Forbid ();
  556.   for (node = GfxBase->TextFonts.lh_Head; node->ln_Succ;
  557.        node = node->ln_Succ)
  558.     {
  559.       tf = (TEXTFONT *) node;
  560.  
  561.       o_cnt = tf->tf_Accessors;
  562.  
  563.       if ((o_cnt == 0) && (tf->tf_Flags & FPF_DISKFONT))
  564.     {
  565.       /*
  566.        * hold open count, font name
  567.        */
  568.       post_flush[post_cnt].o_cnt = o_cnt;
  569.       post_flush[post_cnt].confeds.fonts.font_x = tf->tf_XSize;
  570.       post_flush[post_cnt].confeds.fonts.font_y = tf->tf_YSize;
  571.       strncpy (post_flush[post_cnt].name, node->ln_Name, S_BUFLEN - 1);
  572.  
  573.       ++post_cnt;
  574.     }
  575.     }
  576.   Permit ();
  577.  
  578.   printf ("Fonts    : total = %2d , flushable = %2d, flushed = %2d\n",
  579.       font_cnt, pre_cnt, pre_cnt - post_cnt);
  580.  
  581.   if (pre_cnt && v_flag)
  582.     {
  583.       /*
  584.        * now see how many fonts were flushed
  585.        */
  586.       for (j = 0; j < pre_cnt; ++j)
  587.     {
  588.       char *l_name = pre_flush[j].name;
  589.  
  590.       if (!check_flushed (post_cnt, post_flush, l_name))
  591.         {
  592.           printf ("\tFlushed         :  %-27s(X=%2d,Y=%2d)\n", l_name,
  593.               pre_flush[j].confeds.fonts.font_x,
  594.               pre_flush[j].confeds.fonts.font_y);
  595.         }
  596.     }
  597.       /*
  598.        * now see how many fonts were not flushed
  599.        */
  600.  
  601.       for (j = 0; j < post_cnt; ++j)
  602.     {
  603.       char *l_name = post_flush[j].name;
  604.  
  605.       printf ("\tNot Flushed     :  %-27s(X=%2d,Y=%2d)\n", l_name,
  606.           post_flush[j].confeds.fonts.font_x,
  607.           post_flush[j].confeds.fonts.font_y);
  608.     }
  609.       printf ("\n");
  610.     }
  611.  
  612.   return;
  613. }
  614.  
  615. /*
  616.  **********************************************************
  617.  */
  618.  
  619. int
  620. GetListCount (LIST * list)
  621. {
  622.   int count = 0;
  623.   NODE *node;
  624.  
  625.   Forbid ();
  626.  
  627.   for (node = list->lh_Head; node->ln_Succ; node = node->ln_Succ)
  628.     count++;
  629.  
  630.   Permit ();
  631.  
  632.   return count;
  633. }
  634.  
  635.  
  636. /*
  637.  **********************************************************
  638.  */
  639.  
  640. void
  641. memm (ULONG * fast, ULONG * chipx)
  642. {
  643.   *fast = AvailMem (MEMF_FAST);
  644.   *chipx = AvailMem (MEMF_CHIP);
  645. }
  646.  
  647.  
  648. /*
  649.  **********************************************************
  650.  */
  651.  
  652. BOOL
  653. check_flushed (int count, S_LIB * s_ptr, char *n_ptr)
  654. {
  655.   int j;
  656.  
  657.   for (j = 0; j < count; ++j)
  658.     {
  659.       if (strcmp (s_ptr[j].name, n_ptr) == 0)
  660.     return TRUE;
  661.     }
  662.   return FALSE;
  663. }
  664.  
  665. /*
  666.  **********************************************************
  667.  */
  668.  
  669. void
  670. GetItemsBuf (S_LIB ** pre, S_LIB ** post)
  671. {
  672.   ULONG bf, bl, bd;
  673.   ULONG v;
  674.  
  675.   bf = GetListCount (&GfxBase->TextFonts);
  676.   bl = GetListCount (&SysBase->LibList);
  677.   bd = GetListCount (&SysBase->DeviceList);
  678.  
  679.   v = max (bf, bl);
  680.   v = max (v, bd);
  681.  
  682.   /*
  683.    * increase the entry count a bit for safety
  684.    */
  685.  
  686.   v += 10;
  687.  
  688.  
  689.   if ((*pre = malloc (v * sizeof (S_LIB))) == NULL)
  690.     {
  691.       fprintf (stderr, "Can't malloc pre-buffer\n");
  692.       exit (1);
  693.     }
  694.   if ((*post = malloc (v * sizeof (S_LIB))) == NULL)
  695.     {
  696.       fprintf (stderr, "Can't malloc post-buffer\n");
  697.       exit (1);
  698.     }
  699. }
  700.  
  701. /*
  702.  **********************************************************
  703.  */
  704.  
  705. void
  706. usage ()
  707. {
  708.  
  709.   printf (
  710.        "Flush: flushes unused libraries, devices, fonts from RAM\n\
  711. Version %s [%s] written by gduncan@philips.oz.au\n\n\
  712. usage: flush [-d] [-f] [-l] [-v] [-r] [-h] [-oOBJ]\n\
  713.     -d    ; only flush devices\n\
  714.     -f    ; only flush fonts\n\
  715.     -l    ; only flush libraries\n\
  716.     -r    ; report only; don't flush\n\
  717.     -v    ; be verbose; print names of all removed objects\n\
  718.     -oOBJ ; remove OBJ , must have a suffix of .library or .device\n\
  719.     -h    ; this message\n",
  720.  
  721.        VERSION, __DATE__);
  722.  
  723. }
  724.  
  725. /***************************************************************************
  726.  
  727.  
  728.  Function :     scan_args
  729.  
  730.  Purpose:       scans and validates command line
  731.  
  732.  Entry    :
  733.  
  734.  
  735.  Returns  :
  736.  
  737.  
  738.  
  739.  ****************************************************************************/
  740.  
  741.  
  742.  
  743. void
  744. scan_args (int argc, char **argv)
  745.  
  746. {
  747.   char *ptr;
  748.   char arch;
  749.  
  750.   while (--argc)
  751.     {
  752.       ptr = *++argv;
  753.  
  754.       arch = *++ptr;
  755.       switch (arch)
  756.     {
  757.  
  758.     case 'h':
  759.       usage ();
  760.       exit (1);
  761.  
  762.     case 'd':
  763.       d_flag = TRUE;
  764.       break;
  765.  
  766.     case 'f':
  767.       f_flag = TRUE;
  768.       break;
  769.  
  770.     case 'l':
  771.       l_flag = TRUE;
  772.       break;
  773.  
  774.     case 'v':
  775.       v_flag = TRUE;
  776.       break;
  777.  
  778.     case 'r':
  779.       r_flag = TRUE;
  780.       break;
  781.  
  782.     case 'o':
  783.       o_flag = TRUE;
  784.       remove_it = ++ptr;
  785.       break;
  786.  
  787.     default:
  788.       fprintf (stderr, "unknown option\n");        /* bad option   */
  789.       exit (1);
  790.     }
  791.     }
  792. }
  793.  
  794. /*
  795.  **********************************************************
  796.  */
  797.  
  798. void
  799. rem_obj (char *ptr)
  800. {
  801.   char *z;
  802.   NODE *lp;
  803.  
  804.   if ((z = strstr (ptr, ".library")) != NULL)
  805.     {
  806.       if ((lp = (NODE *) FindName ((LIST *) SysBase->LibList.lh_Head, ptr)))
  807.     RemLibrary ((LIBRARY *) lp);
  808.     }
  809.   else if ((z = strstr (ptr, ".device")) != NULL)
  810.     {
  811.       if ((lp = (NODE *) FindName ((LIST *) SysBase->DeviceList.lh_Head, ptr)))
  812.     RemDevice ((DEVICE *) lp);
  813.     }
  814.   else
  815.     fprintf (stderr, "not a .device or .library\n");
  816.  
  817. }
  818.  
  819. /**/
  820.