home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 345_01 / tlcutil.c < prev    next >
C/C++ Source or Header  |  1989-07-10  |  10KB  |  432 lines

  1. /* TLCUTIL.C - "The Last Cross-referencer" - General utility routines    */
  2. /*    Last Modified:    02/10/89                                            */
  3.  
  4. /*
  5. ---------------------------------------------------------------------
  6. Copyright (c) 1987-1989, Eduard Schwan Programs [esp] - All rights reserved
  7. TLC (The Last C-Cross-Referencer) and TLP (same, but for Pascal) are
  8. Cross-Reference Generators crafted and shot into the Public Domain by
  9. Eduard Schwan.  The source code and executable program may be freely
  10. distributed as long as the copyright/author notices remain intact, and
  11. it is not used in part or whole as the basis of a commercial product.
  12. Any comments, bug-fixes, or enhancements are welcome.
  13. Also, if you find TLC and it's source code useful, a contribution of
  14. $20 (check/money order) is encouraged!  Hopefully we will all see more
  15. source code distributed!
  16.     Eduard Schwan, 1112 Oceanic Drive, Encinitas, Calif. 92024
  17. ---------------------------------------------------------------------
  18. */
  19.  
  20. /*
  21. HEADER:        The Last Cross-Referencer;
  22. TITLE:        TLC/TLP - The Last Cross-Referencer;
  23. VERSION:    1.01;
  24.  
  25. DESCRIPTION: "TLC/TLP.
  26.             General utility routines";
  27.  
  28. KEYWORDS:    Utility, Cross-reference, C, Pascal, Apple, Macintosh, APW, Aztec;
  29. SYSTEM:        Macintosh MPW, v3.0;
  30. FILENAME:    TLCUTIL.C;
  31. WARNINGS:    "Has not yet been ported to MS-DOS.
  32.             Shareware, $20 Check/Money Order suggested.";
  33.  
  34. SEE-ALSO:    README.TLC,TLCHELP.DOC,TLPHELP.DOC;
  35. AUTHORS:    Eduard Schwan;
  36. COMPILERS:    AZTEC C65 v3.2b, APPLEIIGS APW C v1.0, APPLE MACINTOSH MPW C v3.0;
  37. */
  38.  
  39.  
  40. /*-------------------------- include files ---------------------------*/
  41.  
  42. #include    <stdio.h>
  43. #include    <errno.h>
  44. #include    <memory.h>
  45. #include    <ctype.h>
  46. #ifdef macintosh
  47. #include    <osutils.h>    /* for date/time routines */
  48. #endif
  49. #include    "tlc.h"
  50.  
  51.  
  52. /*------------------------ external declarations ----------------------*/
  53.  
  54. #include    "tlc.ext"
  55. #ifdef AppleIIgs
  56. #include <shell.h>       /* this has STOP() macro for check_user_abort() fn */
  57. #endif
  58.  
  59. #ifdef AppleIIgs
  60. extern long     time();  /* these are in 2/time.lib in APW */
  61. extern char *    ctime();
  62. #endif
  63.  
  64.  
  65. /*--------------------------- definitions ----------------------------*/
  66.  
  67. #ifndef isdigit
  68. #define     isdigit(c)        ((c) >= '0' && (c) <= '9')
  69. #endif
  70.  
  71.  
  72. /*-------------------------- static variables ------------------------*/
  73.  
  74. static char ctime_str[DATE_SIZE]; /* ASCII date/time buffer for ctime() */
  75.  
  76. static char * week_days[] =
  77.     {
  78.     "Sun",
  79.     "Mon",
  80.     "Tue",
  81.     "Wed",
  82.     "Thu",
  83.     "Fri",
  84.     "Sat"
  85.     };
  86.  
  87.  
  88. /*---------------------------- functions -----------------------------*/
  89.  
  90.  
  91. /*=================[ open_text_file ]===================*/
  92.  
  93. FILE * open_text_file(fname, options, error_ptr)
  94. char*    fname;
  95. char*    options;
  96. int*    error_ptr;
  97.  
  98.     { /* open_text_file() */
  99.     FILE * fp;
  100.  
  101.     errno = 0;
  102.     fp=fopen(fname, options);
  103.     *error_ptr = errno;
  104. debug(printf("open_text_file:fname='%s,%s' err=%x\n",fname,options,errno);)
  105.     return(fp);
  106.     } /* open_text_file() */
  107.  
  108.  
  109.  
  110. /*=================[ close_text_file ]===================*/
  111.  
  112. int close_text_file(fp, fname)
  113. FILE*    fp;
  114. char*    fname; /* NOTE: so far, only needed for debug */
  115.  
  116.     { /* close_text_file() */
  117.     int    err;
  118.     
  119.     errno = 0;
  120.     fclose(fp);
  121.     err = errno;
  122. debug(printf("close_text_file:'%s' errno=%d\n",fname,err);)
  123.     return(err);
  124.     } /* close_text_file() */
  125.  
  126.  
  127.  
  128. /*=================[ do_emphasis ]===================*/
  129.  
  130. VOID do_emphasis(emph_type)
  131. byte    emph_type;
  132.  
  133.     { /* do_emphasis() */
  134.     char * leadin;
  135.  
  136.     if (emph_type != EMPH_NONE)
  137.         { /* do some kind of leadin */
  138.         if (emph_type >= EMPH_MAX)
  139.             { /* out of range */
  140.             fprintf(stderr,
  141.                 "Error! DoEmphasis (%d) out of range!\n",emph_type);
  142.             exit(1);
  143.             }
  144.         else
  145.             { /* send leadin sequence */
  146.             emph_type--; /* 1..MAX ==> 0..MAX-1 for array indexing */
  147.             leadin = emph_array[emph_type].emph_leadin;
  148.             fprintf(out_file, leadin);
  149. debug(printf("do_emph[%d] = '%s'\n",emph_type,leadin);)
  150.             }
  151.         }
  152.     } /* do_emphasis() */
  153.  
  154.  
  155.  
  156. /*=================[ undo_emphasis ]===================*/
  157.  
  158. VOID undo_emphasis(emph_type)
  159. byte    emph_type;
  160.  
  161.     { /* undo_emphasis() */
  162.     char * leadout;
  163.  
  164.     if (emph_type != EMPH_NONE)
  165.         { /* do some kind of leadin */
  166.         if (emph_type >= EMPH_MAX)
  167.             { /* out of range */
  168.             fprintf(stderr,
  169.                 "Error! UndoEmphasis (%d) out of range!\n",emph_type);
  170.             exit(1);
  171.             }
  172.         else
  173.             { /* send leadout sequence */
  174.             emph_type--; /* 1..MAX ==> 0..MAX-1 for array indexing */
  175.             leadout = emph_array[emph_type].emph_leadout;
  176.             fprintf(out_file, leadout);
  177. debug(printf("do_emph[%d] = '%s'\n",emph_type,leadout);)
  178.             }
  179.         }
  180.     } /* undo_emphasis() */
  181.  
  182.  
  183.  
  184. /*==================[ do_form_feed ]====================*/
  185. /* WARNING! incremented line_num not passed back if !has_form_feed*/
  186. /* does this matter?.. */
  187. VOID do_form_feed(out_file, line_num)
  188. FILE * out_file;
  189. int    line_num;
  190. { /* do_form_feed() */
  191.     if (parm_rec.has_form_feed)
  192.         { /* do a true form feed to printer */
  193.         putc(CH_FF, out_file);
  194.         }
  195.     else
  196.         { /* fake a form feed by advancing n more lines */
  197.         while (line_num < parm_rec.page_lines)
  198.             {
  199.             putc('\n', out_file);
  200.             line_num++;
  201.             }
  202.         }
  203. } /* do_form_feed() */
  204.  
  205.  
  206. /*=====================[ indent ]=======================*/
  207.  
  208. VOID indent()
  209.  
  210. { /* indent() */
  211. pos_int k;
  212.  
  213. debug(puts("indent:");)
  214. for (k=1; k<parm_rec.left_column; k++)
  215.    putc(' ', out_file);
  216. } /* indent() */
  217.  
  218.  
  219.  
  220. /*==================[ get_time ]========================*/
  221.  
  222. VOID get_time(time_str)
  223. char    *time_str;
  224.  
  225.     { /* get_time() */
  226. #ifdef AppleIIgs
  227.     static int    time_rec[10];  /* buffer that time() uses for date/time */
  228.  
  229.     time(&time_rec[0]);
  230.     strcpy(time_str, ctime(&time_rec[0]));
  231.     /* eliminate trailing \n if there */
  232.     if (time_str[strlen(time_str)-1] < ' ')
  233.         time_str[strlen(time_str)-1] = '\0';
  234. #else
  235. #ifdef macintosh
  236.     DateTimeRec    date_rec;
  237.     
  238.     GetTime(&date_rec);
  239.     sprintf(time_str, "%s %2d/%02d/%02d  %2d:%02d",
  240.             week_days[date_rec.dayOfWeek-1],
  241.             date_rec.month, date_rec.day, date_rec.year,
  242.             date_rec.hour, date_rec.minute);
  243. #endif
  244. #endif
  245.     } /* get_time() */
  246.  
  247.  
  248.  
  249. /*==================[ get_freemem ]========================*/
  250.  
  251. long get_freemem()
  252.  
  253.     { /* get_freemem() */
  254. #ifdef AppleIIgs
  255.     return FreeMem();
  256. #else
  257. #ifdef macintosh
  258.     return FreeMem();
  259. #endif
  260. #endif
  261.     } /* get_freemem() */
  262.  
  263.  
  264.  
  265. /*==================[ check_user_abort ]===================*/
  266.  
  267. VOID check_user_abort()
  268.  
  269.     { /* check_user_abort() */
  270. #ifdef AppleIIgs
  271.     if (STOP())
  272. #else
  273. #ifdef macintosh
  274.     if (FALSE)
  275. #else
  276.     if (keypressed())
  277. #endif
  278. #endif
  279.         { /* clean up and exit */
  280.         fprintf(stderr,"\n\nUser Break Anticipated and Understood!  Bye..\n");
  281.         fflush(stderr);
  282.         close(out_file);
  283.         exit(1);
  284.         }
  285.     } /* check_user_abort() */
  286.  
  287.  
  288.  
  289. /*=================[ ok_to_print ]===============*/
  290.  
  291. int ok_to_print()
  292.  
  293.     { /* ok_to_print() */
  294. /*debug(printf("okToPrint(): 1stPg=%d currPg=%d lastPg=%d\n",\
  295. parm_rec.first_page, out_page_number, parm_rec.last_page);)*/
  296.     if ((out_page_number >= parm_rec.first_page) &&
  297.         (out_page_number <= parm_rec.last_page))
  298.         return(TRUE);
  299.     else
  300.         return(FALSE);
  301.     } /* ok_to_print() */
  302.  
  303.  
  304.  
  305. /*==================[ new_page ]===================*/
  306.  
  307. VOID new_page(do_output, who, page_ptr, line_ptr, file_name)
  308. boolean        do_output;
  309. char *        who;
  310. pos_int *    page_ptr;
  311. pos_int *    line_ptr;
  312. char *        file_name;
  313.  
  314.     { /* new_page() */
  315.  
  316.     /* next page, first line */
  317.     (*page_ptr)++;
  318.     *line_ptr = 0;
  319.  
  320.     if (ok_to_print() && do_output)
  321.         {
  322.         /* go to new page */
  323.         do_form_feed(out_file, *line_ptr);
  324.         }
  325.  
  326.     if (ok_to_print() && do_output)
  327.         {
  328.         /* do first line of heading */
  329.         indent();
  330.         do_emphasis(parm_rec.emph_heading);
  331.         fprintf(out_file,"The Last Cross-referencer [%s]  %-6s      Page %u",
  332.                 TLC_VERSION, who, *page_ptr);
  333.         if (file_name != NULL)
  334.             fprintf(out_file,"  %s", file_name);
  335.         undo_emphasis(parm_rec.emph_heading);
  336.         putc('\n', out_file);
  337.         }
  338.     (*line_ptr)++;
  339.  
  340.     /* do second line of heading */
  341.     if (ok_to_print() && do_output)
  342.         {
  343.         indent();
  344.         do_emphasis(parm_rec.emph_heading);
  345.  
  346.         /* put date/time on line.. */
  347.         if (strlen(ctime_str)==0)
  348.             {
  349.             get_time(ctime_str);
  350.             }
  351.         fprintf(out_file, ctime_str);
  352.  
  353.         /* put user heading on line if it exists */
  354.         if (parm_rec.user_heading!=NULL)
  355.             {
  356.             fprintf(out_file, " -- %s", parm_rec.user_heading);
  357.             }
  358.         undo_emphasis(parm_rec.emph_heading);
  359.         putc('\n', out_file);
  360.  
  361.         /* skip a line between heading and data lines */
  362.         putc('\n', out_file);
  363.         } /* if ok_to_print */
  364.     (*line_ptr) += 2;
  365.  
  366.     } /* new_page() */
  367.  
  368.  
  369.  
  370. /*==================[ expand_str_chars ]===================*/
  371.  
  372. VOID expand_str_chars(str)
  373. char *    str;
  374.  
  375.     { /* expand_str_chars() */
  376.     char        ch;
  377.     pos_int     accum_value, base, digit_count;
  378.     char *        str2;
  379.  
  380.     /* start at beginning of string, and move string down as its converted */
  381.     str2 = str;
  382.     while ((ch=*str2) != '\0')
  383.         {
  384.         /* handle special escape characters? */
  385.         if (ch == '\\')
  386.             {
  387.             ch = tolower(*++str2); /* get char after backslash */
  388.  
  389.             /* set base for possible octal/hex digit conversion */
  390.             base = B_octal;
  391.             digit_count = 3; /* three digits max */
  392.             if (ch == 'x')
  393.                 {
  394.                 base = B_hex;
  395.                 digit_count = 2; /* two digits max */
  396.                 ch = tolower(*++str2); /* get 1st hex digit */
  397.                 }
  398.  
  399.             /* see if digits follow the backslash */
  400.             if (isdigit(ch) || (ch>='a' && ch<='f' && base==B_hex))
  401.                 { /* convert digits to a character value */
  402.                 accum_value = 0;
  403.                 do    {
  404.                     if (ch>='a' && ch<='f' && base==B_hex)
  405.                         ch -= 7; /* shift ASCII a..f down to 10..15 */
  406.                     accum_value = accum_value*base + (ch&0x0f);
  407. debug(printf("expStr(): s='%s' val=%d\n",str2,accum_value);)
  408.                     ch = tolower(*++str2);
  409.                     digit_count--;
  410.                     } while (digit_count &&
  411.                         (isdigit(ch)||(base==B_hex && ch>='a' && ch<='f')));
  412.                 /* passed last digit, back up one for second increment */
  413.                 /* below, and put accumulated value in ch so that it   */
  414.                 /* will be put in the string at *str below..           */
  415.                 str2--;
  416.                 ch = accum_value;
  417.                 }
  418.  
  419.             /* if it wasn't a '\nnn' sequence, just drop down & */
  420.             /* copy the char after the '\' into string            */
  421.             }
  422.  
  423.         /* copy this character into the string & move on */
  424.         *str++ = ch;
  425.         str2++;
  426.         } /*while*/
  427.  
  428.         /* terminate the string at the new end */
  429.         *str = '\0';
  430.  
  431.     } /* expand_str_chars() */
  432.