william@CS.UCLA.EDU (William Cheng) (03/11/91)
Submitted-by: william@CS.UCLA.EDU (William Cheng) Posting-number: Volume 12, Issue 20 Archive-name: tgif/part04 ---------------------------------> cut here <--------------------------------- #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 4 (of 23)." # Contents: file.c # Wrapped by william@oahu on Wed Mar 6 09:57:09 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'file.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'file.c'\" else echo shar: Extracting \"'file.c'\" \(41175 characters\) sed "s/^X//" >'file.c' <<'END_OF_FILE' X/* X * Author: William Chia-Wei Cheng (william@cs.ucla.edu) X * X * Copyright (C) 1990, 1991, William Cheng. X */ X#ifndef lint Xstatic char RCSid[] = X "@(#)$Header: /tmp_mnt/n/kona/tangram/u/william/X11/TGIF2/RCS/file.c,v 2.0 91/03/05 14:17:43 william Exp $"; X#endif X X#include <sys/types.h> X#include <sys/file.h> X#include <stdio.h> X#include <signal.h> X#include <X11/Xlib.h> X#include <X11/Xutil.h> X#include "const.h" X#include "types.h" X X#include "align.e" X#include "arc.e" X#include "attr.e" X#include "box.e" X#include "button.e" X#include "choice.e" X#include "color.e" X#include "cursor.e" X#include "dialog.e" X#include "drawing.e" X#include "dup.e" X#include "font.e" X#include "grid.e" X#include "group.e" X#include "mainloop.e" X#include "menu.e" X#include "msg.e" X#include "names.e" X#include "pattern.e" X#include "poly.e" X#include "polygon.e" X#include "prtgif.e" X#include "obj.e" X#include "oval.e" X#include "rcbox.e" X#include "rect.e" X#include "ruler.e" X#include "scroll.e" X#include "select.e" X#include "setup.e" X#include "special.e" X#include "stk.e" X#include "text.e" X#include "xbitmap.e" X X#define CUR_VERSION 10 X#define START_HAVING_ATTRS 8 X Xextern char * getenv (); X Xchar curFileName[MAXPATHLENGTH]; Xint curFileDefined = FALSE; Xint fileVersion = INVALID; Xint importingFile = FALSE; Xint psDotsPerInch = 72; Xchar *psXOffStr[MAXPAGESTYLES]={"0.55","0.4","0.28","0.2","0.565","0.4"}; Xfloat psXOff[MAXPAGESTYLES] = { 0.55, 0.4, 0.28, 0.2, 0.565, 0.4 }; Xchar *psYOffStr[MAXPAGESTYLES]={"10.4","-0.6","10.7","-0.3","10.4","-0.6"}; Xfloat psYOff[MAXPAGESTYLES] = { 10.4, -0.6, 10.7, -0.3, 10.4, -0.6 }; Xchar *psScaleStr[MAXPAGESTYLES]={"0.565","0.565","0.28","0.28","1.13","1.13"}; Xfloat psScale[MAXPAGESTYLES] = { 0.565, 0.565, 0.28, 0.28, 1.13, 1.13 }; Xfloat psPageWidthInInch[MAXPAGESTYLES] = { 7.5, 10, 15.5, 21, 3.75, 5 }; Xfloat psPageHeightInInch[MAXPAGESTYLES] = { 10, 7.5, 21, 15.5, 5, 3.75 }; X Xchar printCommand[MAXSTRING]; X Xvoid ClearFileInfo () X{ X curFileName[0] = '\0'; X curFileDefined = FALSE; X *curSymDir = '\0'; X} X Xint OkayToCreateFile (FileName) X char * FileName; X{ X FILE * fp; X X if ((fp = fopen (FileName, "r")) == NULL) return (TRUE); X fclose (fp); X switch (YesNoCancel ("File exists, okay to overwrite? [ync](y)")) X { X case CONFIRM_YES: break; X case CONFIRM_NO: return (FALSE); X case CONFIRM_CANCEL: return (FALSE); X } X unlink (FileName); X return (TRUE); X} X Xvoid Save (FP, BotObjPtr, Level) X FILE * FP; X struct ObjRec * BotObjPtr; X int Level; X{ X struct ObjRec * obj_ptr; X X TieLooseEnds (); X X if (Level == 0) X { X fprintf (FP, "state(%1d,%1d,", pageStyle, CUR_VERSION); X fprintf (FP, "%1d,%1d,%1d,", drawOrigX, drawOrigY, zoomScale); X fprintf (FP, "%1d,%1d,%1d,", xyGrid, gridOn, colorIndex); X fprintf (FP, "%1d,%1d,%1d,", horiAlign, vertAlign, lineWidth); X fprintf (FP, "%1d,%1d,%1d,%1d,", curSpline, lineStyle, objFill, penPat); X fprintf (FP, "%1d,%1d,%1d,%1d,", textJust, curFont, curStyle, curSize); X fprintf (FP, "%1d,%1d).\n", curFontDPI, curDash); X X fprintf (FP, "%%\n"); X fprintf (FP, "%% @%s%s\n", "(#)$H", "eader$"); X fprintf (FP, "%%\n"); X } X X for (obj_ptr = BotObjPtr; obj_ptr != NULL; obj_ptr = obj_ptr->prev) X { X switch (obj_ptr->type) X { X case OBJ_POLY: SavePolyObj (FP, obj_ptr); break; X case OBJ_BOX: SaveBoxObj (FP, obj_ptr); break; X case OBJ_OVAL: SaveOvalObj (FP, obj_ptr); break; X case OBJ_TEXT: SaveTextObj (FP, obj_ptr); break; X case OBJ_POLYGON: SavePolygonObj (FP, obj_ptr); break; X case OBJ_ARC: SaveArcObj (FP, obj_ptr); break; X case OBJ_RCBOX: SaveRCBoxObj (FP, obj_ptr); break; X case OBJ_XBM: SaveXBmObj (FP, obj_ptr); break; X case OBJ_GROUP: SaveGroupObj (FP, obj_ptr, Level); break; X case OBJ_SYM: SaveCompObj (FP, obj_ptr, Level); break; X case OBJ_ICON: SaveIconObj (FP, obj_ptr, Level); break; X } X if (obj_ptr->prev == NULL) X if (Level == 0) X fprintf (FP, ".\n"); X else X fprintf (FP, "\n"); X else X if (Level == 0) X fprintf (FP, ".\n"); X else X fprintf (FP, ",\n"); X } X SetCurChoice (NOTHING); X} X X#define OBJ_FILE_SAVED 0 X#define SYM_FILE_SAVED 1 X Xstatic Xint SaveTmpFile (NewFileName) X char * NewFileName; X /* return TRUE if file successfully saved */ X{ X char new_file_name[MAXPATHLENGTH], s[MAXPATHLENGTH]; X FILE * fp; X int count = 0, status = INVALID; X struct ObjRec * obj_ptr; X X strcpy (new_file_name, NewFileName); X X for (obj_ptr = topObj; obj_ptr != NULL; obj_ptr = obj_ptr->next) X if (obj_ptr->type == OBJ_SYM) count++; X X switch (count) X { X case 0: strcat (new_file_name, ".obj"); status = OBJ_FILE_SAVED; break; X case 1: strcat (new_file_name, ".sym"); status = SYM_FILE_SAVED; break; X default: X Msg ("TOO MANY SYMBOLS! Symbol file not saved."); X return (INVALID); X } X X unlink (new_file_name); X X if ((fp = fopen (new_file_name, "w")) == NULL) X { X sprintf (s, "Can not open '%s', file not saved.", new_file_name); X Msg (s); X return (INVALID); X } X X sprintf (s, "Saving temporary file '%s' ...", new_file_name); X Msg (s); X Save (fp, botObj, 0); X fclose (fp); X sprintf (s, "Temporary file '%s' saved.", new_file_name); X Msg (s); X X chmod (new_file_name, 0777); X return (status); X} X Xvoid SaveNewFile () X{ X char new_file_name[MAXPATHLENGTH], s[MAXPATHLENGTH]; X char new_full_name[MAXPATHLENGTH], tmp_str[MAXPATHLENGTH]; X char name_without_ext[MAXPATHLENGTH]; X FILE * fp; X int count = 0, len; X struct ObjRec * obj_ptr; X X Dialog ("Please Enter New File Name:", new_file_name); X if (*new_file_name == '\0') return; X len = strlen (new_file_name); X X for (obj_ptr = topObj; obj_ptr != NULL; obj_ptr = obj_ptr->next) X if (obj_ptr->type == OBJ_SYM) count++; X X switch (count) X { X case 0: X if (len >= 4) X { X if (strcmp (&new_file_name[len-4], ".sym") == 0) X { X Msg ("Can not save as a .sym file, no symbol defined."); X return; X } X else if (strcmp (&new_file_name[len-4], ".obj") != 0) X { X strcpy (name_without_ext, new_file_name); X strcat (new_file_name, ".obj"); X } X else X { X strcpy (name_without_ext, new_file_name); X name_without_ext[len-4] = '\0'; X } X X if (strlen (new_file_name) == 4) X { X Msg ("No file name specified. File not saved."); X return; X } X } X else X { X strcpy (name_without_ext, new_file_name); X strcat (new_file_name, ".obj"); X } X break; X case 1: X if (len >= 4) X { X if (strcmp (&new_file_name[len-4], ".obj") == 0) X { X Msg ("Can not save as a .obj file, ther is a symbol defined."); X return; X } X else if (strcmp (&new_file_name[len-4], ".sym") != 0) X { X strcpy (name_without_ext, new_file_name); X strcat (new_file_name, ".sym"); X } X else X { X strcpy (name_without_ext, new_file_name); X name_without_ext[len-4] = '\0'; X } X X if (strlen (new_file_name) == 4) X { X Msg ("No file name specified. File not saved."); X return; X } X } X else X { X strcpy (name_without_ext, new_file_name); X strcat (new_file_name, ".sym"); X } X break; X default: X Msg ("TOO MANY SYMBOLS! Symbol file not saved."); X return; X } X X if (*new_file_name == '/') X strcpy (new_full_name, new_file_name); X else X sprintf (new_full_name, "%s/%s", curDir, new_file_name); X X if (!OkayToCreateFile (new_full_name)) return; X X if ((fp = fopen (new_full_name, "w")) == NULL) X { X sprintf (s, "Can not open '%s', file not saved.", new_full_name); X Msg (s); X return; X } X X strcpy (tmp_str, curDir); X SetCurDir (new_full_name); X curFileDefined = TRUE; X X switch (count) X { X case 0: X *curSymDir = '\0'; X if ((strcmp (tmp_str, curDir) != 0) || (!NameInCurDir (curFileName))) X UpdateDirInfo (); X break; X case 1: X strcpy (curSymDir, curDir); X if (!DirInSymPath (curDir)) UpdateSymInfo (); X break; X } X X sprintf (s, "Saving '%s/%s' ...", curDir, curFileName); X Msg (s); X Save (fp, botObj, 0); X fclose (fp); X sprintf (s, "File '%s/%s' saved.", curDir, curFileName); X Msg (s); X SetFileModified (FALSE); X X RedrawTitleWindow (); X} X Xvoid SaveFile () X{ X int i, len, count; X struct ObjRec * obj_ptr; X FILE * fp; X char ext[MAXPATHLENGTH], s[MAXPATHLENGTH]; X char full_name[MAXPATHLENGTH]; X X if (!curFileDefined) X { X SaveNewFile (); X return; X } X X len = strlen (curFileName); X for (i = len-1; curFileName[i] != '.'; i--) ; X strcpy (ext, &curFileName[i+1]); X X for (obj_ptr = topObj, count = 0; obj_ptr != NULL; obj_ptr = obj_ptr->next) X if (obj_ptr->type == OBJ_SYM) count++; X switch (count) X { X case 0: X if (strcmp (ext, "sym") == 0) X { X Msg ("No SYMBOL defined in symbol file. Symbol file not saved."); X return; X } X break; X case 1: X if (strcmp (ext, "obj") == 0) X { X Msg ("One SYMBOL defined in OBJECT file. Object file not saved."); X return; X } X break; X default: X if (strcmp (ext, "sym") == 0) X { X Msg ("Too many SYMBOLS in symbol file! Symbol file not saved."); X return; X } X break; X } X X if (strcmp (ext, "sym") == 0) X sprintf (full_name, "%s/%s", curSymDir, curFileName); X else if (strcmp (ext, "obj") == 0) X sprintf (full_name, "%s/%s", curDir, curFileName); X X if ((fp = fopen (full_name, "w")) == NULL) X { X sprintf (s, "Can not open '%s', file not saved.", full_name); X Msg (s); X return; X } X X sprintf (s, "Saving '%s' ...", full_name); X Msg (s); X X Save (fp, botObj, 0); X X fclose (fp); X sprintf (s, "File '%s' saved.", full_name); X Msg (s); X SetFileModified (FALSE); X if (!NameInCurDir (curFileName)) UpdateDirInfo (); X} X Xchar * ParseStr (Str, C, Left) X char * Str, C, * Left; X{ X register char * s = Str, * l = Left; X register int len = 0; X X while (*s != '\0' && *s != C) X { X *l++ = *s++; X len++; X } X X if (*s == C) s++; X *l = '\0'; X X while (len >= 2 && *Left == '\'' && *(l-1) == '\'') X { X *(--l) = '\0'; X strcpy (Left, &Left[1]); X len -= 2; X } X return (s); X} X Xchar * FindChar (C, Str) X char C; X char * Str; X /* returns the address of the character right after C of the string Str */ X{ X register char * s = Str; X X while (*s != '\0' && *s != C) s++; X X if (*s == C) s++; X return (s); X} X Xvoid ReadState (Inbuf, PRTGIF) X char * Inbuf; X int PRTGIF; X{ X char * s; X int page_style; X X s = FindChar ('(', Inbuf); X sscanf (s, "%d", &page_style); X s = FindChar (',', s); X if (*s == '\0') X fileVersion = INVALID; X else X sscanf (s, "%d", &fileVersion); X X if (PRTGIF) X { X pageStyle = page_style; X return; X } X X if (!importingFile) X { X pageStyle = page_style; X if (fileVersion >= 2) X { X s = FindChar (',', s); X if (fileVersion <= 3) X { X sscanf (s, "%d , %d , %d , %d , %d , %d , %d , %d , %d , %d , \ X %d , %d , %d , %d , %d , %d", X &drawOrigX, &drawOrigY, &zoomScale, &xyGrid, &gridOn, X &colorIndex, &horiAlign, &vertAlign, &lineWidth, &lineStyle, X &objFill, &penPat, &textJust, &curFont, &curStyle, &curSize); X if (lineWidth == LINE_CURVED) X { X lineWidth = 0; X curSpline = LT_SPLINE; X } X else X curSpline = LT_STRAIGHT; X curFontDPI = FONT_DPI_75; X curDash = 0; X } X else if (fileVersion <= 7) X { X sscanf (s, "%d , %d , %d , %d , %d , %d , %d , %d , %d , \ X %d , %d , %d , %d , %d , %d , %d , %d", X &drawOrigX, &drawOrigY, &zoomScale, &xyGrid, &gridOn, X &colorIndex, &horiAlign, &vertAlign, &lineWidth, &curSpline, X &lineStyle, &objFill, &penPat, &textJust, &curFont, X &curStyle, &curSize); X curFontDPI = FONT_DPI_75; X curDash = 0; X } X else if (fileVersion <= 8) X { X sscanf (s, "%d , %d , %d , %d , %d , %d , %d , %d , %d , \ X %d , %d , %d , %d , %d , %d , %d , %d , %d", X &drawOrigX, &drawOrigY, &zoomScale, &xyGrid, &gridOn, X &colorIndex, &horiAlign, &vertAlign, &lineWidth, &curSpline, X &lineStyle, &objFill, &penPat, &textJust, &curFont, X &curStyle, &curSize, &curFontDPI); X curDash = 0; X } X else X { X sscanf (s, "%d , %d , %d , %d , %d , %d , %d , %d , %d , \ X %d , %d , %d , %d , %d , %d , %d , %d , %d , %d", X &drawOrigX, &drawOrigY, &zoomScale, &xyGrid, &gridOn, X &colorIndex, &horiAlign, &vertAlign, &lineWidth, &curSpline, X &lineStyle, &objFill, &penPat, &textJust, &curFont, X &curStyle, &curSize, &curFontDPI, &curDash); X } X if (colorIndex >= maxColors) X { X printf ("Can not find color #%1d, use '%s' instead.\n", colorIndex, X colorMenuItems[defaultColorIndex]); X colorIndex = defaultColorIndex; X } X SetCanvasFont (); X } X X UpdDrawWinWH (); X UpdPageStyle (pageStyle); X UpdDrawWinBBox (); X X DrawPaperBoundary (); X RedrawGridLines (); X RedrawRulers (); X RedrawChoiceWindow (); X } X} X Xvoid ReadObjAttrs (MinFileVersion, FP, ObjPtr, PRTGIF) X FILE * FP; X struct ObjRec * * ObjPtr; X int PRTGIF; X{ X struct AttrRec * top_attr = NULL, * bot_attr = NULL, * attr_ptr; X X if (fileVersion <= MinFileVersion) return; X X while (ReadAttr (FP, &attr_ptr, PRTGIF)) X { X attr_ptr->owner = *ObjPtr; X attr_ptr->prev = NULL; X attr_ptr->next = top_attr; X if (top_attr == NULL) X bot_attr = attr_ptr; X else X top_attr->prev = attr_ptr; X top_attr = attr_ptr; X } X if (bot_attr != NULL) bot_attr->next = NULL; X (*ObjPtr)->fattr = top_attr; X (*ObjPtr)->lattr = bot_attr; X} X Xint ReadObj (FP, ObjPtr, PRTGIF) X FILE * FP; X struct ObjRec * * ObjPtr; X int PRTGIF; X{ X char inbuf[MAXSTRING+1], obj_name[10], tmp_str[MAXSTRING+1]; X char * line = NULL, * c_ptr, * s, * s1; X int len, id, cur_size, done = FALSE, allocated = FALSE; X X while (fgets (inbuf, MAXSTRING, FP) != NULL) X { X if (inbuf[0] == ']') return (FALSE); X X len = strlen(inbuf); X if (inbuf[len-1] != '\r' && inbuf[len-1] != '\n') X { /* line longer than MAXSTRING characters */ X /* inbuf[MAXSTRING-1] == '\0' and len == MAXSTRING-1 now */ X cur_size = 2*(MAXSTRING-1); X allocated = TRUE; X line = (char *) calloc (cur_size, sizeof(char)); X strcpy (line, inbuf); X c_ptr = &(line[MAXSTRING-1]); X while (!done && fgets (inbuf, MAXSTRING, FP) != NULL) X { X len = strlen(inbuf); X if (inbuf[len-1] == '\r' || inbuf[len-1] == '\n') X { X done = TRUE; X inbuf[len-1] = '\0'; X strcpy (c_ptr, inbuf); X } X else X { X cur_size += MAXSTRING-1; X line = (char *) realloc (line, cur_size); X strcpy (c_ptr, inbuf); X c_ptr += MAXSTRING-1; X } X } X if (!done) X { X if (allocated) cfree (line); X return (FALSE); X } X } X else X { X line = inbuf; X line[len-1] = '\0'; X } X X if (line[0] == '%') X { /* comment line, skip */ X continue; X } X X ParseStr (line, '(', obj_name); X if (strcmp (obj_name, "poly") == 0) X { X ReadPolyObj (line, ObjPtr); X ReadObjAttrs (INVALID, FP, ObjPtr, PRTGIF); X AdjObjBBox (*ObjPtr); X if (allocated) cfree (line); X return (TRUE); X } X else if (strcmp (obj_name, "box") == 0) X { X ReadBoxObj (line, ObjPtr); X ReadObjAttrs (START_HAVING_ATTRS-1, FP, ObjPtr, PRTGIF); X AdjObjBBox (*ObjPtr); X if (allocated) cfree (line); X return (TRUE); X } X else if (strcmp (obj_name, "oval") == 0) X { X ReadOvalObj (line, ObjPtr); X ReadObjAttrs (START_HAVING_ATTRS-1, FP, ObjPtr, PRTGIF); X AdjObjBBox (*ObjPtr); X if (allocated) cfree (line); X return (TRUE); X } X else if (strcmp (obj_name, "text") == 0) X { X ReadTextObj (FP, line, ObjPtr, PRTGIF); X if (allocated) cfree (line); X return (TRUE); X } X else if (strcmp (obj_name, "polygon") == 0) X { X ReadPolygonObj (line, ObjPtr); X ReadObjAttrs (START_HAVING_ATTRS-1, FP, ObjPtr, PRTGIF); X AdjObjBBox (*ObjPtr); X if (allocated) cfree (line); X return (TRUE); X } X else if (strcmp (obj_name, "arc") == 0) X { X ReadArcObj (line, ObjPtr); X ReadObjAttrs (START_HAVING_ATTRS-1, FP, ObjPtr, PRTGIF); X AdjObjBBox (*ObjPtr); X if (allocated) cfree (line); X return (TRUE); X } X else if (strcmp (obj_name, "rcbox") == 0) X { X ReadRCBoxObj (line, ObjPtr); X ReadObjAttrs (START_HAVING_ATTRS-1, FP, ObjPtr, PRTGIF); X AdjObjBBox (*ObjPtr); X if (allocated) cfree (line); X return (TRUE); X } X else if (strcmp (obj_name, "xbm") == 0) X { X ReadXBmObj (FP, line, ObjPtr, PRTGIF); X ReadObjAttrs (START_HAVING_ATTRS-1, FP, ObjPtr, PRTGIF); X AdjObjBBox (*ObjPtr); X if (allocated) cfree (line); X return (TRUE); X } X else if (strcmp (obj_name, "group") == 0) X { X ReadGroupObj (FP, ObjPtr, PRTGIF); X ReadObjAttrs (INVALID, FP, ObjPtr, PRTGIF); X AdjObjBBox (*ObjPtr); X if (allocated) cfree (line); X return (TRUE); X } X else if (strcmp (obj_name, "sym") == 0) X { X ReadGroupObj (FP, ObjPtr, PRTGIF); X (*ObjPtr)->type = OBJ_SYM; X ReadObjAttrs (INVALID, FP, ObjPtr, PRTGIF); X AdjObjBBox (*ObjPtr); X if (allocated) cfree (line); X return (TRUE); X } X else if (strcmp (obj_name, "icon") == 0) X { X ReadGroupObj (FP, ObjPtr, PRTGIF); X (*ObjPtr)->type = OBJ_ICON; X if (fgets (line, MAXSTRING, FP) == NULL) X { X if (allocated) cfree (line); X return (FALSE); X } X X strcpy(tmp_str, FindChar ('"', line)); X s = FindChar ('"', tmp_str); X if (fileVersion != INVALID) X { X s1 = FindChar (',', s); X sscanf (s1, "%d", &id); X if (id >= objId) objId = id+1; X (*ObjPtr)->id = id; X } X (*ObjPtr)->dirty = FALSE; X *(--s) = '\0'; X strcpy ((*ObjPtr)->detail.r->s, tmp_str); X ReadObjAttrs (INVALID, FP, ObjPtr, PRTGIF); X AdjObjBBox (*ObjPtr); X if (allocated) cfree (line); X return (TRUE); X } X else if (strcmp (obj_name, "state") == 0) X { X ReadState (line, PRTGIF); X *ObjPtr = NULL; X if (allocated) cfree (line); X return (TRUE); X } X } X if (allocated) cfree (line); X return (FALSE); X} X Xvoid ChangeDomain () X{ X char domain_name[MAXPATHLENGTH], env_str[MAXPATHLENGTH]; X char s[MAXSTRING], s1[MAXSTRING], * c_ptr; X X if (SelectDomain (domain_name) == INVALID) return; X X sprintf (env_str, "TGIF_%s", domain_name); X if ((c_ptr = getenv (env_str)) == NULL) X ParseSymPath ("."); X else X ParseSymPath (c_ptr); X X UpdateSymInfo (); X X strcpy (curDomainName, domain_name); X sprintf (s, "Current domain is '%s'.", curDomainName); X sprintf (s1, "Symbol path set to '%s'.", curDomainPath); X TwoLineMsg (s, s1); X RedrawTitleWindow (); X} X Xvoid ImportFile () X{ X struct ObjRec * obj_ptr, * saved_top_obj, * saved_bot_obj; X char file_name[MAXPATHLENGTH], s[MAXPATHLENGTH]; X FILE * fp; X X importingFile = TRUE; X if (SelectFileNameToImport ("Please select a file to IMPORT ...", X "obj", file_name) == INVALID) X { X importingFile = FALSE; X return; X } X X strcat (file_name, ".obj"); X X if ((fp = fopen (file_name, "r")) == NULL) X { X sprintf (s, "Can not import '%s'.", file_name); X Msg (s); X importingFile = FALSE; X return; X } X X TieLooseEnds (); X if (topSel != NULL) { HighLightReverse (); RemoveAllSel (); } X saved_top_obj = topObj; X saved_bot_obj = botObj; X topObj = botObj = NULL; X X sprintf (s, "Importing '%s' ...", file_name); X Msg (s); X X while (ReadObj (fp, &obj_ptr, FALSE)) X if (obj_ptr != NULL) X AddObj (NULL, topObj, obj_ptr); X X fclose (fp); X importingFile = FALSE; X if (topObj != NULL) SetFileModified (TRUE); X X RedrawDrawWindow (botObj); X SelAllObj (); X X if (botObj != NULL) X botObj->next = saved_top_obj; X else X topObj = saved_top_obj; X X if (saved_top_obj != NULL) X { X saved_top_obj->prev = botObj; X botObj = saved_bot_obj; X } X X sprintf (s, "'%s' imported.", file_name); X Msg (s); X} X Xvoid ImportXBitmapFile () X{ X char file_name[MAXPATHLENGTH], s[MAXPATHLENGTH]; X unsigned int w, h; X int rc, x_hot, y_hot; X Pixmap bitmap; X X importingFile = TRUE; X if (SelectFileNameToImport ("Please select a XBitmap file to IMPORT ...", X XBM_FILE_EXT, s) == INVALID) X { X importingFile = FALSE; X return; X } X X sprintf (file_name, "%s.%s", s, XBM_FILE_EXT); X X rc = XReadBitmapFile (mainDisplay, mainWindow, file_name, &w, &h, &bitmap, X &x_hot, &y_hot); X X if (rc != BitmapSuccess) X { X sprintf (s, "Can not import XBitmap file '%s'.", file_name); X Msg (s); X importingFile = FALSE; X return; X } X X CreateXBmObj (w, h, bitmap); X X TieLooseEnds (); X if (topSel != NULL) { HighLightReverse (); RemoveAllSel (); } X SetNullCursor (drawWindow); X X PlaceTopObj (); X SelectTopObj (); X SetFileModified (TRUE); X justDupped = FALSE; X ShowCursor (); X X sprintf (s, "XBitmap file (%1dx%1d) '%s' imported.", w, h, file_name); X Msg (s); X importingFile = FALSE; X} X Xvoid LoadFile () X{ X struct ObjRec * obj_ptr; X char file_name[MAXPATHLENGTH], s[MAXPATHLENGTH]; X char saved_cur_dir[MAXPATHLENGTH]; X FILE * fp; X X strcpy (saved_cur_dir, curDir); X if (SelectFileName ("Please select a file to OPEN ...",file_name) == INVALID) X return; X X strcat (file_name, ".obj"); X X if ((fp = fopen (file_name, "r")) == NULL) X { X sprintf (s, "Can not open '%s'.", file_name); X Msg (s); X return; X } X X TieLooseEnds (); X CleanUpDrawingWindow (); X SetFileModified (FALSE); X sprintf (s, "Loading '%s' ...", file_name); X Msg (s); X X XClearWindow (mainDisplay, drawWindow); X X while (ReadObj (fp, &obj_ptr, FALSE)) X if (obj_ptr != NULL) X { X AddObj (NULL, topObj, obj_ptr); X if (PointInBBox (obj_ptr->x, obj_ptr->y, drawWinBBox) || X BBoxIntersect (obj_ptr->bbox, drawWinBBox)) X DrawObj (drawWindow, obj_ptr); X } X X if (topObj == NULL) X { X DrawPaperBoundary (); X RedrawGridLines (); X } X X fclose (fp); X SetCurDir (file_name); X *curSymDir = '\0'; X curFileDefined = TRUE; X X if (strcmp (saved_cur_dir, curDir) != 0 && DirInSymPath (".")) X UpdateSymInfo (); X X sprintf (s, "Current file is '%s'.", file_name); X Msg (s); X X RedrawTitleWindow (); X} X Xvoid DumpPatFill (FP, Fill, CellSize, BBox, Blanks) X FILE * FP; X int Fill, CellSize; X struct BBRec BBox; X char * Blanks; X{ X int ltx, lty, rbx, rby; X X ltx = ((BBox.ltx % CellSize) == 0) ? BBox.ltx : X ((BBox.ltx > 0) ? ((int)(BBox.ltx / CellSize))*CellSize : X ((int)(BBox.ltx / CellSize)-1)*CellSize); X lty = ((BBox.lty % CellSize) == 0) ? BBox.lty : X ((BBox.lty > 0) ? ((int)(BBox.lty / CellSize))*CellSize : X ((int)(BBox.lty / CellSize)-1)*CellSize); X rbx = ((BBox.rbx % CellSize) == 0) ? BBox.rbx : X ((BBox.rbx > 0) ? ((int)(BBox.rbx / CellSize)+1)*CellSize : X ((int)(BBox.rbx / CellSize))*CellSize); X rby = ((BBox.rby % CellSize) == 0) ? BBox.rby : X ((BBox.rby > 0) ? ((int)(BBox.rby / CellSize)+1)*CellSize : X ((int)(BBox.rby / CellSize))*CellSize); X X fprintf (FP, "%spat%1d %1d %1d %1d %1d %1d patfill\n", X Blanks, Fill, CellSize, ltx, lty, rbx-ltx, rby-lty); X} X Xvoid DumpSymOutline (FP, ObjPtr) X FILE * FP; X register struct ObjRec * ObjPtr; X{ X int ltx, lty, rbx, rby; X X ltx = ObjPtr->obbox.ltx - QUARTER_INCH + 1; X lty = ObjPtr->obbox.lty - QUARTER_INCH + 1; X rbx = ObjPtr->obbox.rbx + QUARTER_INCH - 1; X rby = ObjPtr->obbox.rby + QUARTER_INCH - 1; X X fprintf (FP, "gsave\n"); X fprintf (FP, " 0 setgray\n"); X fprintf (FP, " [4 4] 0 setdash\n"); X fprintf (FP, " newpath\n %1d %1d moveto\n", ltx, lty); X fprintf (FP, " %1d %1d lineto\n", rbx, lty); X fprintf (FP, " %1d %1d lineto\n", rbx, rby); X fprintf (FP, " %1d %1d lineto\n", ltx, rby); X fprintf (FP, " closepath stroke\n"); X fprintf (FP, "grestore\n"); X} X Xvoid DumpAttrs (FP, AttrPtr, PRTGIF) X FILE * FP; X register struct AttrRec * AttrPtr; X int PRTGIF; X{ X for ( ; AttrPtr != NULL; AttrPtr = AttrPtr->prev) X if (AttrPtr->shown) X DumpTextObj (FP, AttrPtr->obj, PRTGIF); X} X Xvoid DumpAllObj (FP, ObjPtr, PRTGIF) X FILE * FP; X register struct ObjRec * ObjPtr; X int PRTGIF; X{ X register struct ObjRec * obj_ptr; X X switch (ObjPtr->type) X { X case OBJ_POLY: X DumpPolyObj (FP, ObjPtr); X DumpAttrs (FP, ObjPtr->lattr, PRTGIF); X break; X case OBJ_BOX: X DumpBoxObj (FP, ObjPtr); X DumpAttrs (FP, ObjPtr->lattr, PRTGIF); X break; X case OBJ_OVAL: X DumpOvalObj (FP, ObjPtr); X DumpAttrs (FP, ObjPtr->lattr, PRTGIF); X break; X case OBJ_TEXT: DumpTextObj (FP, ObjPtr, PRTGIF); break; X case OBJ_POLYGON: X DumpPolygonObj (FP, ObjPtr); X DumpAttrs (FP, ObjPtr->lattr, PRTGIF); X break; X case OBJ_ARC: X DumpArcObj (FP, ObjPtr); X DumpAttrs (FP, ObjPtr->lattr, PRTGIF); X break; X case OBJ_RCBOX: X DumpRCBoxObj (FP, ObjPtr); X DumpAttrs (FP, ObjPtr->lattr, PRTGIF); X break; X case OBJ_XBM: X DumpXBmObj (FP, ObjPtr, PRTGIF); X DumpAttrs (FP, ObjPtr->lattr, PRTGIF); X break; X case OBJ_SYM: X case OBJ_ICON: X case OBJ_GROUP: X obj_ptr = ObjPtr->detail.r->last; X for ( ; obj_ptr != NULL; obj_ptr = obj_ptr->prev) X DumpAllObj (FP, obj_ptr, PRTGIF); X DumpAttrs (FP, ObjPtr->lattr, PRTGIF); X if (ObjPtr->type == OBJ_SYM) DumpSymOutline (FP, ObjPtr); X break; X } X} X Xvoid DumpBBox (fp) X FILE * fp; X{ X register struct ObjRec * obj_ptr; X int ltx, lty, rbx, rby; X double llx1, lly1, urx1, ury1; X double real_ps_dots_per_inch = 0.0; X X if ((obj_ptr = topObj) == NULL) X { X fprintf (fp, "%%%%BoundingBox: 0 0 0 0\n"); X printf ("Warning: The PostScript bounding box is empty!\n"); X Msg ("Warning: The PostScript bounding box is empty!\n"); X return; X } X X ltx = obj_ptr->bbox.ltx; lty = obj_ptr->bbox.lty; X rbx = obj_ptr->bbox.rbx; rby = obj_ptr->bbox.rby; X X for (obj_ptr = topObj->next; obj_ptr != NULL; obj_ptr = obj_ptr->next) X { X if (obj_ptr->bbox.ltx < ltx) ltx = obj_ptr->bbox.ltx; X if (obj_ptr->bbox.lty < lty) lty = obj_ptr->bbox.lty; X if (obj_ptr->bbox.rbx > rbx) rbx = obj_ptr->bbox.rbx; X if (obj_ptr->bbox.rby > rby) rby = obj_ptr->bbox.rby; X } X X switch (pageStyle) X { X case PORTRAIT: real_ps_dots_per_inch = psDotsPerInch; break; X case LANDSCAPE: real_ps_dots_per_inch = psDotsPerInch; break; X case HIGHPORT: real_ps_dots_per_inch = psDotsPerInch/2.0; break; X case HIGHLAND: real_ps_dots_per_inch = psDotsPerInch/2.0; break; X case SLIDEPORT: real_ps_dots_per_inch = psDotsPerInch*2.0; break; X case SLIDELAND: real_ps_dots_per_inch = psDotsPerInch*2.0; break; X } X X llx1 = 1.0*ltx*real_ps_dots_per_inch/(PIX_PER_INCH); X lly1 = -1.0*rby*real_ps_dots_per_inch/(PIX_PER_INCH); X urx1 = 1.0*rbx*real_ps_dots_per_inch/(PIX_PER_INCH); X ury1 = -1.0*lty*real_ps_dots_per_inch/(PIX_PER_INCH); X X fprintf (fp,"%%%%BoundingBox: %.3f %.3f %.3f %.3f\n",llx1,lly1,urx1,ury1); X} X Xstatic Xvoid GenDump (PRTGIF, FileName) X int PRTGIF; X char * FileName; X{ X register struct ObjRec * obj_ptr; X char cmd[MAXSTRING+1], tmp_str[MAXSTRING+1]; X char tmp_file[MAXSTRING+1], ps_file[MAXSTRING+1]; X char message[MAXSTRING+1]; X int i, len; X FILE * fp, * fps; X X if (botObj == NULL) { Msg ("No object to print."); return; } X X if (!PRTGIF) Msg ("Generating print file ..."); X X if (whereToPrint == XBM_FILE) X { X if (!curFileDefined) X { X if (colorDump) X Dialog ("No current file. Can not generate X11 pitmap output!", X cmd); X else X Dialog ("No current file. Can not generate X11 bitmap output!", X cmd); X } X else X DumpXBitmapFile (); X return; X } X X strcpy (tmp_file, "/tmp/TgifXXXXXX"); X mktemp (tmp_file); X unlink (tmp_file); X X if ((fp = fopen (tmp_file, "w")) == NULL) X { X if (PRTGIF) X printf ("Can not create '%s', print aborted.", tmp_file); X else X { X sprintf (tmp_str, "Can not create '%s', print aborted.", tmp_file); X Msg (tmp_str); X } X return; X } X X if (PRTGIF) printf ("Writing to '%s' ...\n", tmp_file); X X fprintf (fp, "%%!\n"); X DumpBBox (fp); X sprintf(ps_file, "%s/.psmac", drawPath); X if ((fps = fopen (ps_file, "r")) == NULL) X { X if (PRTGIF) X printf ("Can not find '%s', print aborted.\n", ps_file); X else X { X sprintf (message, "Can not find '%s', print aborted.", ps_file); X Msg (message); X } X fclose (fp); X unlink (tmp_file); X return; X } X while (fgets (tmp_str, MAXSTRING, fps) != NULL) /* copy the header file */ X fputs (tmp_str, fp); X fclose (fps); X X fprintf (fp, "gsave\n\n"); X switch (pageStyle) X { X case LANDSCAPE: X case HIGHLAND: X case SLIDELAND: fprintf (fp, "90 rotate\n"); break; X } X switch (whereToPrint) X { X case PRINTER: X case PS_FILE: X fprintf (fp, "%1d %s mul %1d %s mul translate\n", psDotsPerInch, X psXOffStr[pageStyle], psDotsPerInch, psYOffStr[pageStyle]); X break; X case LATEX_FIG: break; X } X X fprintf (fp, "%s -%s scale\n\n", X psScaleStr[pageStyle], psScaleStr[pageStyle]); X X for (obj_ptr = botObj; obj_ptr != NULL; obj_ptr = obj_ptr->prev) X DumpAllObj (fp, obj_ptr, PRTGIF); X X fprintf (fp, "grestore\n\n"); X switch (whereToPrint) X { X case PRINTER: X case PS_FILE: fprintf (fp, "showpage\n"); break; X case LATEX_FIG: break; X } X fclose (fp); X X switch (whereToPrint) X { X case PRINTER: X if (PRTGIF) X { X if (lastFile) X sprintf (cmd, "%s %s 2>&1", printCommand, tmp_file); X else X sprintf (cmd, "%s -h %s 2>&1", printCommand, tmp_file); X } X else X { X sprintf (cmd, "%s %s 2>&1", printCommand, tmp_file); X sprintf (message, "Printing with '%s' command.", printCommand); X Msg (message); X } X break; X case LATEX_FIG: X if (PRTGIF) X sprintf (ps_file, "%s.%s", FileName, EPSF_FILE_EXT); X else X { X if (!curFileDefined) X { X Dialog ("No current file. Can not generate LaTeX output!", cmd); X unlink (tmp_file); X return; X } X sprintf (ps_file, "%s/%s", curDir, curFileName); X len = strlen (ps_file); X for (i = len-1; ps_file[i] != '.'; i--) ; X sprintf (&ps_file[i], ".%s", EPSF_FILE_EXT); X sprintf (cmd, "Printing into '%s'.", ps_file); X Msg (cmd); X } X sprintf (cmd, "cat %s 1> %s 2>&1; chmod %s %s", tmp_file, ps_file, X PSFILE_MOD, ps_file); X break; X case PS_FILE: X if (PRTGIF) X sprintf (ps_file, "%s.%s", FileName, PS_FILE_EXT); X else X { X if (!curFileDefined) X { X Dialog ("No current file. Can not generate PostScript output!", X cmd); X unlink (tmp_file); X return; X } X sprintf (ps_file, "%s/%s", curDir, curFileName); X len = strlen (ps_file); X for (i = len-1; ps_file[i] != '.'; i--) ; X sprintf (&ps_file[i], ".%s", PS_FILE_EXT); X sprintf (cmd, "Printing into '%s'.", ps_file); X Msg (cmd); X } X sprintf (cmd, "cat %s 1> %s 2>&1; chmod %s %s", tmp_file, ps_file, X PSFILE_MOD, ps_file); X break; X } X X if ((fp = popen (cmd, "r")) == NULL) X { X if (PRTGIF) X printf ("Can not execute '%s', print aborted.\n", cmd); X else X { X sprintf (message, "Can not execute '%s', print aborted.", cmd); X Msg (message); X } X unlink (tmp_file); X return; X } X while (fgets(tmp_str, MAXSTRING, fp) != NULL) X { X if (PRTGIF) X printf ("%s", tmp_str); X else X Msg (tmp_str); X sleep (5); X } X switch (whereToPrint) X { X case PRINTER: X if (PRTGIF) X printf ("'%s' printed.\n\n", tmp_file); X else X Msg ("Print completed."); X break; X case PS_FILE: X if (PRTGIF) X printf ("PostScript file printed into '%s'.\n\n", ps_file); X else X { X sprintf (message, "PostScript file printed into '%s'.", ps_file); X Msg (message); X } X break; X case LATEX_FIG: X if (PRTGIF) X printf ("LaTeX figure printed into '%s'.\n\n", ps_file); X else X { X sprintf (message, "LaTeX figure printed into '%s'.", ps_file); X Msg (message); X } X break; X } X pclose (fp); X unlink (tmp_file); X} X Xvoid Dump (PRTGIF, FileName) X int PRTGIF; X char * FileName; X{ X char * c_ptr; X int len; X X if (PRTGIF) X { X len = strlen (FileName); X if (len >= 4 && strcmp (&FileName[len-4], ".obj") == 0) X FileName[len-4] = '\0'; X } X X if (whereToPrint == PRINTER && !PRTGIF) X { X if ((c_ptr = XGetDefault (mainDisplay, "Tgif", "PrintCommand")) != NULL) X strcpy (printCommand, c_ptr); X else X strcpy (printCommand, "lpr"); X } X GenDump (PRTGIF, FileName); X} X Xvoid PrintWithCommand (PRTGIF, FileName) X int PRTGIF; X char * FileName; X{ X if (whereToPrint == PRINTER) X { X Dialog ("Please Enter Print Command Name:", printCommand); X if (*printCommand == '\0') return; X } X GenDump (PRTGIF, FileName); X} X Xvoid NewProc () X{ X if (fileModified) X { X switch (YesNoCancel ("File modified, save file before clear? [ync](y)")) X { X case CONFIRM_YES: SaveFile (); break; X case CONFIRM_NO: TieLooseEnds (); break; X case CONFIRM_CANCEL: return; X } X SetFileModified (FALSE); X } X CleanUpDrawingWindow (); X ClearFileInfo (); X ClearAndRedrawDrawWindow (); X Msg ("Editing no file."); X objId = 0; X RedrawTitleWindow (); X} X Xvoid OpenProc () X{ X if (fileModified) X { X switch (YesNoCancel ("File modified, save file before open? [ync](y)")) X { X case CONFIRM_YES: SaveFile (); break; X case CONFIRM_NO: break; X case CONFIRM_CANCEL: return; X } X } X LoadFile (); X} X X#define FILE_NEW 0 X#define FILE_OPEN 1 X#define FILE_SAVE 2 X#define FILE_SAVENEW 3 X#define FILE_IMPORT 4 X#define FILE_IMPORTXBM 5 X#define FILE_DOMAIN 6 X#define FILE_DUMP 7 X#define FILE_USR_DUMP 8 X#define FILE_SOLVE 9 X#define FILE_SIMULATE 10 X#define FILE_PROBE 11 X#define FILE_ANIMATE 12 X#define FILE_ESCAPE 13 X#define FILE_QUIT 14 X X#define FILEMENUENTRIES 15 X Xchar * fileMenuStr[] = X { "New ^N", X "Open ^O", X "Save ^S", X "SaveNew ^#S", X "Import #P", X "ImportXBitmap ^#P", X "ChangeDomain ^C", X "Print ^P", X "PrintWithCmd ^-", X "Solve #S", X "Simulate #Y", X "Probe #B", X "Animate ^Z", X "Escape #X", X "Quit ^Q" X }; X Xint QuitProc () X{ X if (fileModified) X { X switch (YesNoCancel ("File modified, save file before quit? [ync](y)")) X { X case CONFIRM_YES: SaveFile (); break; X case CONFIRM_NO: break; X case CONFIRM_CANCEL: return (INVALID); X } X } X if (AncesterModified ()) X { X switch (YesNoCancel ("Ancester file modified, still quitting? [ync](y)")) X { X case CONFIRM_YES: return (FILE_QUIT); X case CONFIRM_NO: return (INVALID); X case CONFIRM_CANCEL: return (INVALID); X } X } X return (FILE_QUIT); X} X Xint SolveProc () X{ X switch (SaveTmpFile ("tmpmodel")) X { X case OBJ_FILE_SAVED: return (FILE_SOLVE); X case SYM_FILE_SAVED: return (INVALID); X case INVALID: return (INVALID); X } X} X Xint SimulateProc () X{ X switch (SaveTmpFile ("tmpmodel")) X { X case OBJ_FILE_SAVED: return (FILE_SIMULATE); X case SYM_FILE_SAVED: return (INVALID); X case INVALID: return (INVALID); X } X} X Xint ProbeProc () X{ X switch (SaveTmpFile ("tmpmodel")) X { X case OBJ_FILE_SAVED: return (FILE_PROBE); X case SYM_FILE_SAVED: return (INVALID); X case INVALID: return (INVALID); X } X} X Xint AnimateProc () X{ X switch (SaveTmpFile ("tmpmodel")) X { X case OBJ_FILE_SAVED: return (FILE_ANIMATE); X case SYM_FILE_SAVED: return (INVALID); X case INVALID: return (INVALID); X } X} X Xint EscapeProc () X{ X return (FILE_ESCAPE); X} X Xint FileMenu (X, Y) X int X, Y; X{ X register int index; X int * fore_colors, * valid; X X DefaultColorArrays (FILEMENUENTRIES, &fore_colors, &valid); X index = TextMenuLoop (X, Y, fileMenuStr, FILEMENUENTRIES, fore_colors, X valid, SINGLECOLOR); X switch (index) X { X case FILE_NEW: NewProc (); break; X case FILE_OPEN: OpenProc (); break; X case FILE_SAVE: SaveFile (); break; X case FILE_SAVENEW: SaveNewFile (); break; X case FILE_IMPORT: ImportFile (); break; X case FILE_IMPORTXBM: ImportXBitmapFile (); break; X case FILE_DOMAIN: ChangeDomain (); break; X case FILE_DUMP: Dump (FALSE, ""); break; X case FILE_USR_DUMP: PrintWithCommand (FALSE, ""); break; X case FILE_SOLVE: return (SolveProc ()); X case FILE_SIMULATE: return (SimulateProc ()); X case FILE_PROBE: return (ProbeProc ()); X case FILE_ANIMATE: return (AnimateProc ()); X case FILE_ESCAPE: return (EscapeProc ()); X case FILE_QUIT: return (QuitProc ()); X } X return (INVALID); X} X Xvoid CleanUpFiles () X{ X ClearFileInfo (); X fileModified = FALSE; X} X Xvoid EmergencySave () X{ X if (exitNormally) return; X X signal (SIGHUP, SIG_DFL); X signal (SIGFPE, SIG_DFL); X signal (SIGBUS, SIG_DFL); X signal (SIGSEGV, SIG_DFL); X X switch (SaveTmpFile ("EmergencySave")) X { X case OBJ_FILE_SAVED: X fprintf (stderr, "Saved to EmergencySave.obj.\n"); X break; X case SYM_FILE_SAVED: X fprintf (stderr, "Saved to EmergencySave.sym.\n"); X break; X case INVALID: X fprintf (stderr, "Unable to save working file.\n"); X break; X } X exitNormally = TRUE; X exit (0); X} X Xint EmergencySaveForX (dsp, ev) X Display * dsp; X XErrorEvent * ev; X{ X if (exitNormally) return (0); X X signal (SIGHUP, SIG_DFL); X signal (SIGFPE, SIG_DFL); X signal (SIGBUS, SIG_DFL); X signal (SIGSEGV, SIG_DFL); X X switch (SaveTmpFile ("EmergencySave")) X { X case OBJ_FILE_SAVED: X fprintf (stderr, "Saved to EmergencySave.obj.\n"); X break; X case SYM_FILE_SAVED: X fprintf (stderr, "Saved to EmergencySave.sym.\n"); X break; X case INVALID: X fprintf (stderr, "Unable to save working file.\n"); X break; X } X exitNormally = TRUE; X return (-1); X} END_OF_FILE if test 41175 -ne `wc -c <'file.c'`; then echo shar: \"'file.c'\" unpacked with wrong size! fi # end of 'file.c' fi echo shar: End of archive 4 \(of 23\). cp /dev/null ark4isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 23 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 ---------------------------------> cut here <--------------------------------- -- Bill Cheng // UCLA Computer Science Department // (213) 206-7135 3277 Boelter Hall // Los Angeles, California 90024 // USA william@CS.UCLA.EDU ...!{uunet|ucbvax}!cs.ucla.edu!william