Main Page | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

mfile.c

Go to the documentation of this file.
00001 /*****************************************************************************\
00002  *  Copyright  1994  The Board of Trustees of the University of Illinois.
00003  *  All rights reserved.
00004  *
00005  *  mfile.c, part of the IMPACT in-memory file interface
00006  *  John C. Gyllenhaal, Wen-mei Hwu, and The IMPACT Research Group
00007  *  Coordinated Science Laboratory
00008  *  University of Illinois at Urbana-Champaign
00009  *
00010  *  The IMPACT Research Group may be contacted at impact@crhc.uiuc.edu.
00011  *
00012  *  mfile.c (part of the IMPACT in-memory file interface),
00013  *  including both binary and source (hereafter, Software) is copyrighted by
00014  *  The Board of Trustees of the University of Illinois (UI),
00015  *  and ownership remains with the UI.
00016  *
00017  *  The UI grants you (hereafter, Licensee) a license to use the Software for
00018  *  academic, research and internal business purposes only, without a fee.
00019  *  Licensee may distribute the Software to third parties provided that the
00020  *  copyright notice and this statement appears on all copies and that no
00021  *  charge is associated with such copies.
00022  *
00023  *  Licensee may make derivative works.  However, if Licensee distributes
00024  *  any derivative work based on or derived from the Software, then Licensee
00025  *  will clearly notify users that such derivative work is a modified
00026  *  version and not the original Software distributed by the UI.
00027  *
00028  *  Any Licensee wishing to make commercial use of the Software should contact
00029  *  the UI, c/o the Research and Technology Management Office [rtmo@uiuc.edu],
00030  *  to negotiate an appropriate license for such commercial use.  Commercial
00031  *  use includes (1) integration of all or part of the source code into a
00032  *  product for sale or license by or on behalf of Licensee to third parties,
00033  *  or (2) distribution of the Software to third parties that need it to
00034  *  utilize a commercial product sold or licensed by or on behalf of Licensee.
00035  *
00036  *  UI MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR
00037  *  ANY PURPOSE.  IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
00038  *  THE UI SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY THE USERS OF THIS
00039  *  SOFTWARE.
00040  *
00041  *  By using or copying this Software, Licensee agrees to abide by the
00042  *  copyright law and all other applicable laws of the U.S. including, but
00043  *  not limited to, export control laws, and the terms of this license.
00044  *  UI shall have the right to terminate this license immediately by written
00045  *  notice upon Licensee's breach of, or non-compliance with, any of its terms.
00046  *  Licensee may be held legally responsible for any copyright infringement
00047  *  that is caused or encouraged by Licensee's failure to abide by the terms
00048  *  of this license.
00049  *
00050  *  Form approved by University Counsel, M.A.R., 05/10/93
00051 \*****************************************************************************/
00052 /*****************************************************************************\
00053  *
00054  *  File:  mfile.c
00055  *
00056  *  Description:  The IMPACT in-memory file interface
00057  *
00058  *  Creation Date :  October 1994
00059  *
00060  *  Authors:  John C. Gyllenhaal, Wen-mei Hwu
00061  *
00062  *  Revisions:
00063  *
00064 \*****************************************************************************/
00065 
00066 #ifndef lint
00067 #define lint
00068 static char copyright[] =
00069 "@(#) Copyright (c) 1994 The Board of Trustees of the University of Illinois.\
00070 \nAll rights reserved.\n";
00071 #endif
00072 
00073 
00074 #include <stdio.h>
00075 #include <stdlib.h>
00076 #include <string.h>
00077 
00078 #include "mfile.h"
00079 #include "l_punt.h"
00080 
00081 /* Declare external functions that must be defined by user */
00082 void L_punt (char *msg, ...);
00083 
00084 /* Alloc pools */
00085 L_Alloc_Pool *Mfile_pool = NULL;
00086 L_Alloc_Pool *Mline_pool = NULL;
00087 L_Alloc_Pool *Mptr_pool = NULL;
00088 
00089 /* Print out buffer and put an arrow to the character specified */
00090 void print_buf_with_arrow (FILE *out, char *buf, int pos)
00091 {
00092     int i, ch;
00093     int col, arrow_col;
00094 
00095     /* Start in column 0 */
00096     col = 0;
00097     arrow_col = 0;
00098 
00099     /* Print out text, upto newline after pos.
00100      * (Since expanded text can have many newlines in it)
00101      */
00102     for (i=0; buf[i] != 0; i++)
00103     {
00104         ch = buf[i];
00105 
00106         /* Get column arrow should go at */
00107         if (i == pos)
00108             arrow_col = col;
00109 
00110         col++;
00111 
00112         /* Expand tabs */
00113         if (ch == '\t')
00114         {
00115             /* Put out first character */
00116             putc (' ', out);
00117 
00118             /* Add spaces until at multiple of 8 */
00119             while ((col % 8) != 0)
00120             {
00121                 col++;
00122                 putc (' ', out);
00123             }
00124 
00125         }
00126         else
00127             putc (ch, out);
00128 
00129         /* Handle newlines */
00130         if (ch == '\n')
00131         {
00132             /* Return to column 0 at newline */
00133                 col = 0;
00134 
00135             /* Stop at newline after pos */
00136             if (i >= pos)
00137                 break;
00138         }
00139     }
00140 
00141     /* Get column arrow should go at (if past end of buf) */
00142     if (i <= pos)
00143         arrow_col = col;
00144     
00145     /* Add trailing newline if none in buffer */
00146     if (buf[i] != '\n')
00147         putc ('\n', out);
00148     
00149 
00150 
00151     /* Put arrow at appropriate column detected in above loop */
00152     for (i=0; i < arrow_col;i++)
00153         putc (' ', out);
00154     fprintf (out, "^\n");
00155 }
00156 
00157 
00158 /*
00159  * Mfile error handler.
00160  * First argument is a mptr that points to where the error occured.
00161  * The second argument is a printf format string, and the rest
00162  * are the arguments for the format string.
00163  */
00164 void Merror (Mptr *mptr, char *fmt, ...)
00165 {
00166     va_list     args;
00167 
00168     /* 
00169      * Print out text line of text where error occured and put arrow to
00170      * location.  (pos starts at 0, so add 1 to get column)
00171      */
00172     fprintf (stderr, "\n");
00173     /* If not at EOF */
00174     if (mptr->mline != NULL)
00175     {
00176         fprintf (stderr, 
00177                  "Error during %s (line %i char %i of %s):\n",
00178                  mptr->mfile->desc,
00179                  mptr->mline->line_no, 
00180                  mptr->pos+1, mptr->mfile->name);
00181     }
00182     /* If at EOF */
00183     else
00184     {
00185         fprintf (stderr, 
00186                  "Error during %s (%s at EOF):\n",
00187                  mptr->mfile->desc,
00188                  mptr->mfile->name);
00189     }
00190 
00191     /*Print error message */
00192     va_start (args, fmt);
00193     vfprintf (stderr, fmt, args);
00194     va_end(args);
00195     fprintf (stderr,"\n");
00196     fprintf (stderr, "\n");
00197 
00198     /* Do not print out file text if at EOF */
00199     if (mptr->mline != NULL)
00200     {
00201         /* Print out file text where error occurred */
00202         fprintf (stderr, "File text where error occurred:\n");
00203         print_buf_with_arrow (stderr, mptr->mline->buf, mptr->pos);
00204     }
00205 
00206     fprintf (stderr,"Fatal error, cannot continue.\n");
00207     fprintf (stderr,"\n");
00208 
00209     exit (-1);
00210 }
00211 
00212 /* Loads file into memory (Mfile structure) and returns a newly 
00213  * allocated Mfile structure.
00214  */
00215 Mfile *create_Mfile (FILE *in, char *input_file_name, char *desc)
00216 {
00217     Mfile *mfile;
00218     Mline *mline;
00219     Mbuf *mbuf;
00220     int ch;
00221     int len;
00222 
00223     /* Allocate structure for Mfile, create pools if necessary */
00224     if (Mfile_pool == NULL)
00225     {
00226         Mfile_pool = L_create_alloc_pool ("Mfile", sizeof (Mfile), 16);
00227     }
00228     if (Mline_pool == NULL)
00229     {
00230         Mline_pool = L_create_alloc_pool ("Mline", sizeof(Mline), 256);
00231     }
00232 
00233     mfile = (Mfile *) L_alloc (Mfile_pool);
00234 
00235     /* Initialize fields */
00236     mfile->name = strdup (input_file_name);
00237     mfile->desc = strdup (desc);
00238     mfile->head = 0;
00239     mfile->tail = 0;
00240     mfile->line_count = 0;
00241 
00242     /* Create mbuf for file */
00243     mbuf = create_Mbuf();
00244 
00245     /* Read in file */
00246     while (1)
00247     {
00248         /* Clear mbuf so we can put the next line it it */
00249         clear_Mbuf (mbuf);
00250 
00251         while ((ch = getc(in)) != EOF)
00252         {
00253             /* Add character to mbuf */
00254             addc_to_Mbuf (mbuf, ch);
00255 
00256             /* If hit newline, end line */
00257             if (ch == '\n')
00258                 break;
00259         }
00260 
00261         /* Add line if Mbuf not empty */
00262         if ((len = len_of_Mbuf (mbuf)) > 0)
00263         {
00264             /* Increment line count */
00265             mfile->line_count++;
00266 
00267             /* Allocate a Mline for this line */
00268             mline = (Mline *) L_alloc (Mline_pool);
00269 
00270             /* Init contents of line */
00271             mline->buf = copy_Mbuf_buf (mbuf);
00272             mline->len = len;
00273             mline->line_no = mfile->line_count;
00274             mline->mfile = mfile;
00275             
00276             /* Add to mfile's linked list of lines */
00277             if (mfile->tail == NULL)
00278                 mfile->head = mline;
00279             else
00280                 mfile->tail->next = mline;
00281             mline->prev = mfile->tail;
00282             mline->next = NULL;
00283             mfile->tail = mline;
00284         }
00285 
00286         /* Stop at EOF */
00287         if (ch == EOF)
00288             break;
00289     }
00290 
00291     /* Free up allocated memory */
00292     free_Mbuf (mbuf);
00293 
00294     return (mfile);
00295 }
00296 
00297 /* Free memory Mfile is using */
00298 void free_Mfile (Mfile *mfile)
00299 {
00300     Mline *mline, *next_mline;
00301 
00302     /* Free all the lines in the mfile */
00303     for (mline = mfile->head; mline != NULL; mline = next_mline)
00304     {
00305         /* Get next mline before we delete anything */
00306         next_mline = mline->next;
00307 
00308         /* Free buffer and L_free structure */
00309         free (mline->buf);
00310         L_free (Mline_pool, mline);
00311     }
00312 
00313     /* Free name buffer and L_free structure */
00314     free (mfile->name);
00315     free (mfile->desc);
00316     L_free (Mfile_pool, mfile);
00317 }
00318 
00319 /* Create mptr to start of mfile */
00320 Mptr *create_Mptr (Mfile *mfile)
00321 {
00322     Mptr *mptr;
00323 
00324     if (Mptr_pool == NULL)
00325     {
00326         Mptr_pool = L_create_alloc_pool ("Mptr", sizeof (Mptr), 16);
00327     }
00328     mptr = (Mptr *) L_alloc (Mptr_pool);
00329     
00330     mptr->mfile = mfile;
00331     mptr->mline = mfile->head;
00332     mptr->pos = 0;
00333 
00334     return (mptr);
00335 }
00336 /* Duplicates a Mptr exactly 
00337  * Returns the duplicated Mptr (must be freed)
00338  */
00339 Mptr *copy_Mptr (Mptr *orig_mptr)
00340 {
00341     Mptr *new_mptr;
00342     
00343     /* alloc and copy over fields */
00344     new_mptr = (Mptr *) L_alloc (Mptr_pool);
00345 
00346     new_mptr->mfile = orig_mptr->mfile;
00347     new_mptr->mline = orig_mptr->mline;
00348     new_mptr->pos = orig_mptr->pos;
00349     
00350     return (new_mptr);
00351 }
00352 
00353 /* Moves the old mptr to the new mptr location */
00354 void move_Mptr (Mptr *old_mptr, Mptr *new_mptr)
00355 {
00356     old_mptr->mfile = new_mptr->mfile;
00357     old_mptr->mline = new_mptr->mline;
00358     old_mptr->pos = new_mptr->pos;
00359 }
00360 
00361 
00362 void free_Mptr (Mptr *mptr)
00363 {
00364     /* L_free structure */
00365     L_free (Mptr_pool, mptr);
00366 }
00367 
00368 /* Gets the next character from the mfile. */
00369 int Mgetc (Mptr *mptr)
00370 {
00371     int ch;
00372 
00373     /* If at EOF, return EOF */
00374     if (mptr->mline == NULL)
00375         return (EOF);
00376 
00377     /* Get next character in file */
00378     ch = mptr->mline->buf[mptr->pos];
00379 
00380     /* Goto next character, and next line if necessary */
00381     mptr->pos++;
00382     if (mptr->pos >= mptr->mline->len)
00383     {
00384         mptr->mline = mptr->mline->next;
00385         mptr->pos = 0;
00386     }
00387 
00388     return (ch);
00389 }
00390 
00391 /* Returns char position on line of Mptr */
00392 int Mptr_pos (Mptr *mptr)
00393 {
00394     return (mptr->pos);
00395 }
00396 
00397 /* Peeks at the next character from the mfile. */
00398 int Mpeekc (Mptr *mptr)
00399 {
00400     char ch;
00401 
00402     if (mptr->mline == NULL)
00403         ch = EOF;
00404     else
00405         ch = mptr->mline->buf[mptr->pos];
00406 
00407     return (ch);
00408 }
00409 
00410 /* Backup one character in the file.
00411  * Cannot backup before beginning of file.
00412  */
00413 void Mbackupc (Mptr *mptr)
00414 {
00415     /* If at EOF, goto last character in file */
00416     if (mptr->mline == NULL)
00417     {
00418         mptr->mline = mptr->mfile->tail;
00419         if (mptr->mline != NULL)
00420             mptr->pos = mptr->mline->len - 1; 
00421     }
00422     
00423     /* If at beginning of file, goto end of last line */
00424     else if (mptr->pos == 0)
00425     {
00426         mptr->mline = mptr->mline->prev;
00427         if (mptr->mline != NULL)
00428             mptr->pos = mptr->mline->len - 1; 
00429         else
00430             L_punt ("Mbackupc: backing up before beginning of file.");
00431     }
00432 
00433     /* Otherwise, just go backwards one character */
00434     else
00435     {
00436         mptr->pos--;
00437     }
00438 }
00439 

Generated on Mon Jul 21 20:28:04 2003 for TINKER LEGO DOC by doxygen 1.3.2