eddyg@cogs.sussex.ac.uk (EdwardJ. Groenendaal) (05/19/91)
Submitted-by: Edward "J." Groenendaal <eddyg@cogs.sussex.ac.uk> Posting-number: Volume 13, Issue 15 Archive-name: xdtm/part10 Submitted-by: eddyg@cste Archive-name: xdtm/part10 ---- Cut Here and feed the following to sh ---- #!/bin/sh # This is part 10 of xdtm # ============= xdtm/parse.c ============== if test ! -d 'xdtm'; then echo 'x - creating directory xdtm' mkdir 'xdtm' fi if test -f 'xdtm/parse.c' -a X"$1" != X"-c"; then echo 'x - skipping xdtm/parse.c (File already exists)' else echo 'x - extracting xdtm/parse.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'xdtm/parse.c' && X/***************************************************************************** X ** File : parse.c ** X ** Purpose : Parse setup file, select icon to be used. ** X ** Author : Edward Groenendaal ** X ** Date : 19th Feb 1991 ** X ** Documentation : Xdtm Design Folder ** X *****************************************************************************/ X X#include "xdtm.h" X X#include <sys/types.h> X#include <sys/stat.h> X#include <sys/param.h> X X#ifndef TRUE_SYSV X#include <sys/file.h> X#endif X X#include <pwd.h> X#include <grp.h> X#include "parse.h" X#include "menus.h" X X#include "Xedw/XedwList.h" X X#include "bitmaps/Grey.Mask" X#include "bitmaps/folder.icon" X#include "bitmaps/file.icon" X Xtypedef struct _BTree { X Pixmap icon; X Pixmap grey; X struct _BTree *left; X struct _BTree *right; X} BTree; X Xextern FILE *yyin; Xextern int step(char*, char*); Xextern int circf; Xextern typePrefs *prefs ; X X#ifdef ESIX Xtypedef long uid_t /* jcc */ X#endif X Xpublic uid_t user; Xpublic uid_t group; Xprivate BTree *grey_tree; X Xprivate Pixmap applyprefs(typePrefs*, String, String, struct stat*); Xprivate Pixmap do_iconprefs(iconPrefs*, String, String, struct stat*); X Xpublic GC xdtmgc; Xpublic Pixmap foldericon, fileicon, grey_mask; /* default icons */ X X/***************************************************************************** X * getIconType * X *****************************************************************************/ Xpublic Boolean getIconType(String filename, String path, XedwList *element) X{ X /* Return True if file should be displayed, otherwise False. X * if long listing is on, expand the filename to contain the extra X * data as well. X */ X X private Pixmap grey_icon(Pixmap); X X extern Icon_mode current_mode; X struct stat *filestatus; X typePrefs *myprefs = prefs; X String fullname; X Pixmap icon; X X element->string = XtNewString(filename); X X if (current_mode.mode != Short) { X filestatus = (struct stat*) XtMalloc (sizeof(struct stat)); X fullname=(String) XtMalloc((strlen(filename)+strlen(path)+4) * X sizeof(char)); X strcpy(fullname, path); X strcat(fullname, "/"); X strcat(fullname, filename); X#ifdef TRUE_SYSV X if (stat(fullname, filestatus) == -1) { /* jcc, no symbolic links */ X#else X if (lstat(fullname, filestatus) == -1) { X#endif X /* maybe a link to a nonexistent file? */ X return(False); X } else { X if (current_mode.mode == Icons) { X element->icon = fileicon; X if ((filestatus->st_mode & S_IFMT) == S_IFDIR) /* stat(5) for details */ X element->icon = foldericon; X X /* try all rules in prefs */ X if ((icon = applyprefs(myprefs, fullname, filename, filestatus)) != NULL) { X X /* If the file is a directory but is not readable AND executable by the user X * then grey it. If the file is not readable then grey it. X */ X X /* if not readable then grey it */ X if (icon != DUMMY) X if (!(((filestatus->st_mode & S_IRUSR) != 0 && X user == filestatus->st_uid) || X ((filestatus->st_mode & S_IRGRP) != 0 && X group == filestatus->st_gid) || X ((filestatus->st_mode & S_IROTH) != 0))) { X icon = grey_icon(icon); X } else { X if ((filestatus->st_mode & S_IFMT) == S_IFDIR) X if (!(((filestatus->st_mode & S_IXUSR) != 0 && X user == filestatus->st_uid) || X ((filestatus->st_mode & S_IXGRP) != 0 && X group == filestatus->st_gid) || X ((filestatus->st_mode & S_IXOTH) != 0))) { X icon = grey_icon(icon); X } X } X element->icon = icon; X } X } else { X /* Long Listing, construct the line*/ X Cardinal length; X char cm = current_mode.options; X String output_line; X X element->icon = NULL; X length = 0; X output_line = XtNewString(""); X if (cm & PERMS) { X char type; X char xusr, xgrp, xoth; X unsigned short mode = (filestatus->st_mode); X X output_line = (String) XtMalloc (sizeof(char) * 12); X X /* I could use the S_IS* macros here but I prefer to see what's X * going on. X */ X if ((mode & S_IFMT) == S_IFDIR) type = 'd'; /* Directory */ X else if ((mode & S_IFMT) == S_IFBLK) type = 'b'; /* Block device */ X else if ((mode & S_IFMT) == S_IFCHR) type = 'c'; /* Character device */ X else if ((mode & S_IFMT) == S_IFREG) type = ' '; /* Plain file */ X else if ((mode & S_IFMT) == S_IFIFO) type = 'f'; /* Fifo */ X#ifndef TRUE_SYSV /* jcc */ X else if ((mode & S_IFMT) == S_IFLNK) type = 'l'; /* Symbolic link */ X else if ((mode & S_IFMT) == S_IFSOCK) type = 's'; /* Socket */ X#endif X else type = '?'; X X if (mode & S_ISUID) /* Set User Id */ X xusr = 's'; X else if (mode & S_IXUSR) X xusr = 'x'; X else X xusr = '-'; X X if (mode & S_ISGID) /* Set Group Id */ X xgrp = 's'; X else if (mode & S_IXGRP) X xgrp = 'x'; X else X xgrp = '-'; X X if (mode & S_ISVTX) /* Save Text */ X xoth = 't'; X else if (mode & S_IXOTH) X xoth = 'x'; X else X xoth = '-'; X X sprintf(output_line, X "%c%c%c%c%c%c%c%c%c%c ", X type, X (mode & S_IRUSR) ? 'r' : '-', X (mode & S_IWUSR) ? 'w' : '-', X xusr, X (mode & S_IRGRP) ? 'r' : '-', X (mode & S_IWGRP) ? 'w' : '-', X xgrp, X (mode & S_IROTH) ? 'r' : '-', X (mode & S_IWOTH) ? 'w' : '-', X xoth); X } X X if (cm & NLINKS) { X output_line = XtRealloc (output_line, X sizeof(char) * X (strlen(output_line) + 3 + 4)); X X sprintf(output_line, "%s%3d ", output_line, X filestatus->st_nlink); X } X if (cm & OWNER) { X struct passwd *pw; X X output_line = XtRealloc (output_line, X sizeof(char) * X (strlen(output_line) + 8 + 4)); X X if ((pw = getpwuid(filestatus->st_uid)) == NULL) X sprintf(output_line, "%s%-8d ", output_line, filestatus->st_uid); X else X sprintf(output_line, "%s%-8s ", output_line, pw->pw_name); X X } X if (cm & GROUP) { X struct group *gr; X X output_line = XtRealloc (output_line, X sizeof(char) * X (strlen(output_line) + 8 + 4)); X X if ((gr = getgrgid(filestatus->st_gid)) == NULL) X sprintf(output_line, "%s%-8d ", output_line, filestatus->st_gid); X else X sprintf(output_line, "%s%-8s ", output_line, gr->gr_name); X X } X if (cm & SIZE) { X unsigned short mode = (filestatus->st_mode); X X output_line = XtRealloc (output_line, X sizeof(char) * X (strlen(output_line) + 9 + 4)); X if ((mode & S_IFMT) == S_IFBLK || (mode & S_IFMT) == S_IFCHR) X sprintf(output_line, "%s%5d,%3d ", output_line, X (filestatus->st_rdev >> 8) & 0377, X (filestatus->st_rdev) & 0377); X else X sprintf(output_line, "%s%9d ", output_line, filestatus->st_size); X } X if (cm & MODTM) { X String time; X output_line = XtRealloc (output_line, X sizeof(char) * X (strlen(output_line) + 35 + 4)); X X time = ctime(&(filestatus->st_mtime)); X *(time + (strlen(time) - 1)) = '\0'; X sprintf(output_line, "%s%s ", output_line, time); X } X if (cm & ACCTM) { X String time; X output_line = XtRealloc (output_line, X sizeof(char) * X (strlen(output_line) + 35 + 4)); X X time = ctime(&(filestatus->st_atime)); X *(time + (strlen(time) - 1)) = '\0'; X sprintf(output_line, "%s%s ", output_line, time); X } X current_mode.length = strlen(output_line); /* length of data */ X output_line = XtRealloc (output_line, X sizeof(char) * X (strlen(output_line) + strlen(filename) + 4)); X sprintf(output_line, "%s%s", output_line, filename); X element->string = output_line; X } X } X XtFree(filestatus); X XtFree(fullname); X } X X if (element->icon == DUMMY) X return(False); X else X return(True); X} X X/***************************************************************************** X * applyprefs * X *****************************************************************************/ Xprivate Pixmap applyprefs(typePrefs *tp, String fullname, String filename, X struct stat *filestatus) X{ X /* Recursively traverse the prefs structure until a match is found. X * Jump out as soon as a match is found, try special files first */ X X static Boolean insymlink = False; X Pixmap icon = NULL; X struct stat *newfilestatus; X X /* Try directories */ X if (icon == NULL && X tp->dir != NULL && X (filestatus->st_mode & S_IFMT) == S_IFDIR) { X icon = applyprefs(tp->dir, fullname, filename, filestatus); X } X X /* Try plain files */ X if (icon == NULL && X tp->file != NULL && X (filestatus->st_mode & S_IFMT) == S_IFREG) { X icon = applyprefs(tp->file, fullname, filename, filestatus); X } X X /* Try Block special devices */ X if (icon == NULL && X tp->block != NULL && X (filestatus->st_mode & S_IFMT) == S_IFBLK) { X icon = applyprefs(tp->block, fullname, filename, filestatus); X } X X /* Try Character special devices */ X if (icon == NULL && X tp->character != NULL && X (filestatus->st_mode & S_IFMT) == S_IFCHR) { X icon = applyprefs(tp->character, fullname, filename, filestatus); X } X X /* Try Fifo's */ X if (icon == NULL && X tp->fifo != NULL && X (filestatus->st_mode & S_IFMT) == S_IFIFO) { X icon = applyprefs(tp->fifo, fullname, filename, filestatus); X } X X /* Try Symbolic Links */ X if (icon == NULL && X tp->slink != NULL && X insymlink == False && X (filestatus->st_mode & S_IFMT) == S_IFLNK) { X insymlink = True; X newfilestatus = (struct stat*) XtMalloc (sizeof(struct stat)); X if (stat(fullname, newfilestatus) != -1) { X icon = applyprefs(tp->slink, fullname, filename, newfilestatus); X XtFree(newfilestatus); X } X insymlink = False; X } X X /* Try Sockets */ X if (icon == NULL && X tp->socket != NULL && X (filestatus->st_mode & S_IFMT) == S_IFSOCK) { X icon = applyprefs(tp->socket, fullname, filename, filestatus); X } X X /* Try executable files */ X if (icon == NULL && X tp->exe != NULL && X (filestatus->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0) { X icon = applyprefs(tp->exe, fullname, filename, filestatus); X } X X /* Try Readable files */ X if (icon == NULL && X tp->read != NULL && X (filestatus->st_mode & (S_IRUSR | S_IRGRP | S_IROTH)) != 0) { X icon = applyprefs(tp->read, fullname, filename, filestatus); X } X X /* Try Writable files */ X if (icon == NULL && X tp->write != NULL && X (filestatus->st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) != 0) { X icon = applyprefs(tp->write, fullname, filename, filestatus); X } X X /* defaults */ X if (icon == NULL && tp->iconprefs != NULL) { X icon = do_iconprefs(tp->iconprefs, fullname, filename, filestatus); X } X X return(icon); X} X X/***************************************************************************** X * grey_icon * X *****************************************************************************/ Xprivate Pixmap grey_icon(Pixmap icon) X{ X /* Get a greyed icon for the icon 'icon'. */ X X private BTree *grey_search(Pixmap, Pixmap*, BTree*); X Pixmap result; X X grey_tree = grey_search(icon, &result, grey_tree); X X return(result); X} X X/***************************************************************************** X * grey_search * X *****************************************************************************/ Xprivate BTree *grey_search(Pixmap icon, Pixmap *new, BTree *tree) X{ X /* Search through the grey pixmap tree for a pixmap with the same id, X * if none is found, make a new one by And'ing the original icon X * with a stippled pixmap, put this into the tree, and also return it. X * This procedure should still work even if the representation of a X * Pixmap changes. X */ X X Pixmap newpixmap; X Widget w; X BTree *result; X extern Widget topLevel; X X if (tree == NULL) { X /* Create Pixmap */ X result = (BTree*) XtMalloc (sizeof(BTree)); X result->icon = icon; X result->left = NULL; X result->right = NULL; X newpixmap = XCreatePixmap(XtDisplay(topLevel), X RootWindowOfScreen(XtScreen(topLevel)), X 32, 32, DefaultDepthOfScreen(XtScreen(topLevel))); X XSetFunction(XtDisplay(topLevel), xdtmgc, GXcopy); X XCopyPlane(XtDisplay(topLevel), X icon, newpixmap, xdtmgc, 0, 0, 32, 32, 0, 0, 1); X XSetFunction(XtDisplay(topLevel), xdtmgc, GXand); X XCopyPlane(XtDisplay(topLevel), X grey_mask, newpixmap, xdtmgc, 0, 0, 32, 32, 0, 0, 1); X result->grey = newpixmap; X *new = newpixmap; X } else X if (tree->icon == icon) { X /* Found it */ X *new = tree->grey; X result = tree; X } else X if (tree->icon < icon) X /* Try left hand side */ X result = grey_search(icon, new, tree->left); X else X /* Try right hand side */ X result = grey_search(icon, new, tree->right); X X return(result); X} X X/***************************************************************************** X * do_iconprefs * X *****************************************************************************/ Xprivate Pixmap do_iconprefs(iconPrefs *ip, String fullname, String filename, X struct stat *filestatus) X{ X /* traverse linked list trying to match regular expressions against X * the current filename X */ X Pixmap icon = NULL; X String string; X X if (ip != NULL) X if (ip->expbuf == NULL) { X /* default value */ X icon = ip->icon; X } else { X /* try to match regular expression, X */ X if (ip->checkpath == True) X string = fullname; X else X string = filename; X circf = ip->circf; X if (step(string, ip->expbuf) != 0) { X if (ip->extra != NULL) { X icon = applyprefs((typePrefs*)ip->extra, fullname, filename, filestatus); X } X if (icon == NULL) X icon = ip->icon; X } else { X icon = do_iconprefs(ip->next, fullname, filename, filestatus); X } X } X return(icon); X} X X/***************************************************************************** X * parsePreferences * X *****************************************************************************/ Xpublic Boolean parsePreferences(Widget w) X{ X /* Call the parser on the config file */ X X private void initBitmaps(Widget); X extern int yyparse(void); X extern void selectionChange(Widget, Cardinal, caddr_t); X extern typePrefs *newTypePref(void); X extern AppSelection **appselections; X extern Cardinal selectionindex; X extern String home; X extern Widget selectionMenu; X MenuContents *selectionmenu; X String setupfile; X Cardinal i; X int n; X X /* Initialise default pixmaps */ X initBitmaps(w); X X /* check to see it there is an .xdtmrc in the users home directory. X * If not use the system one.. or command line argument one. X */ X X setupfile = (String) XtMalloc ((strlen(home) + 10) * sizeof(char)); X X user = geteuid(); X group = getegid(); X X strcpy(setupfile, home); X strcat(setupfile, "/.xdtmrc"); X if (((yyin = fopen(app_data.cffile, "r")) == NULL) && /* try appdefaults */ X ((yyin = fopen(setupfile, "r")) == NULL) && /* try home dir */ X ((yyin = fopen(SYSTEM_XDTMRC, "r")) == NULL)) { /* try system dir */ X fprintf(stderr, "Error: No user or system xdtmrc found\n"); X fprintf(stderr, " either install an xdtmrc or specify one on the\n"); X fprintf(stderr, " command line using the -cf option\n"); X exit(2); X } else { X /* parse the file */ X (void) yyparse(); X } X XtFree(setupfile); X X /* Create selection menu */ X selectionmenu = (MenuContents*) XtMalloc (sizeof(MenuContents) * X selectionindex); X for(i = 0; i < selectionindex; i++) { X selectionmenu[i].paneName = appselections[i]->name; X selectionmenu[i].paneLabel = appselections[i]->name; X selectionmenu[i].paneNumber = i; X selectionmenu[i].set = noflag; X } X X createMenu(selectionMenu, selectionmenu, i, selectionChange); X X} X X/***************************************************************************** X * initBitmaps * X *****************************************************************************/ Xprivate void initBitmaps(Widget w) X{ X /* Get default icon pixmaps + the stippled pixmap for greying icons */ X X XGCValues values; X X foldericon = XCreateBitmapFromData( XtDisplay(w), X RootWindowOfScreen(XtScreen(w)), X folder_bits, X IconBitmapWidth, IconBitmapHeight); X fileicon = XCreateBitmapFromData( XtDisplay(w), X RootWindowOfScreen(XtScreen(w)), X file_bits, X IconBitmapWidth, IconBitmapHeight); X grey_mask = XCreateBitmapFromData( XtDisplay(w), X RootWindowOfScreen(XtScreen(w)), X Grey_bits, X IconBitmapWidth, IconBitmapHeight); X X /* GC for copying pixmaps */ X if ((BlackPixelOfScreen(XtScreen(w))) == 1) { X values.background = WhitePixelOfScreen(XtScreen(w)); X values.foreground = BlackPixelOfScreen(XtScreen(w)); X } else { X values.background = BlackPixelOfScreen(XtScreen(w)); X values.foreground = WhitePixelOfScreen(XtScreen(w)); X } X X xdtmgc = XtGetGC(w, (unsigned) GCBackground | GCForeground, &values); X X grey_tree = NULL; X} X X/***************************************************************************** X * highlight_by_re * X *****************************************************************************/ Xpublic void highlight_by_re(String re) X{ X /* This procedure is called by selectQueryResult in map.c, it should be in X * map.c but can't because <regexp.h> can only be accessable from within X * one file. X */ X extern void selection_made(Widget, caddr_t, caddr_t); X extern XedwList **icon_list; X extern Cardinal icon_list_size; X extern Widget directoryManager; X String buffer; X Cardinal i; X X buffer = (char*) XtMalloc (sizeof(char) * ESIZE); X compile(re, buffer, &(buffer[ESIZE]), '\0'); X X /* traverse icon_list calling XedwListHighlight on every filename X * matched. X */ X for (i = 0; i < icon_list_size; i++) { X if (step(icon_list[i]->string, buffer) != 0) X XedwListHighlight(directoryManager, i); X } X X selection_made(directoryManager, 0, 0); X X XtFree(buffer); X X} X X X X X X X X X X X X X SHAR_EOF chmod 0644 xdtm/parse.c || echo 'restore of xdtm/parse.c failed' Wc_c="`wc -c < 'xdtm/parse.c'`" test 18463 -eq "$Wc_c" || echo 'xdtm/parse.c: original size 18463, current size' "$Wc_c" fi # ============= xdtm/parse.h ============== if test -f 'xdtm/parse.h' -a X"$1" != X"-c"; then echo 'x - skipping xdtm/parse.h (File already exists)' else echo 'x - extracting xdtm/parse.h (Text)' sed 's/^X//' << 'SHAR_EOF' > 'xdtm/parse.h' && X/***************************************************************************** X ** File : parse.h ** X ** Purpose : ** X ** Author : Edward Groenendaal ** X ** Date : 18th Feb 1991 ** X ** Documentation : Xdtm Design Folder ** X ** Related Files : parse.c, lexical.h, parser.y ** X *****************************************************************************/ X X#ifndef _parse_h X#define _parse_h X X/* Directory Manager Structures */ X Xtypedef struct _iconPrefs { X char *expbuf; X int circf; X Boolean checkpath; X XtPointer extra; X Pixmap icon; X struct _iconPrefs *next; X} iconPrefs; X Xtypedef struct _typePrefs { X iconPrefs *iconprefs; X struct _typePrefs *dir; X struct _typePrefs *file; X struct _typePrefs *block; /* Added in v1.2 */ X struct _typePrefs *character; /* Added in v1.2 */ X struct _typePrefs *fifo; /* Added in v1.2 */ X struct _typePrefs *slink; /* Added in v1.2 */ X struct _typePrefs *socket; /* Added in v1.2 */ X struct _typePrefs *exe; X struct _typePrefs *read; X struct _typePrefs *write; X} typePrefs; X X/* Application Manager Structure */ X X#define APPPSIZE 10 /* Initial size of an AppProgram Array */ X#define APPPINC 5 /* Increment by which to increase AppProgram Array on overflow */ X Xtypedef enum {M_SEL, O_SEL, N_SEL} SelOptions; X Xtypedef struct { X String string; X Pixmap icon; X String program; X SelOptions options; X} AppProgram; X Xtypedef struct { X String name; X Cardinal number; X AppProgram **list; X} AppSelection; X X/* Regular Expression macros */ X X#define ESIZE 1024 /* maximum size of an expression */ X X#define INIT register String sp = instring; X#define GETC() (*sp++) X#define PEEKC() (*sp) X#define UNGETC(c) (--sp) X#define RETURN(c) return; X#define ERROR(c) {fprintf(stderr,"regexp error %d\n", c); exit(1);}; X X#endif /* _parse_h */ SHAR_EOF chmod 0644 xdtm/parse.h || echo 'restore of xdtm/parse.h failed' Wc_c="`wc -c < 'xdtm/parse.h'`" test 2063 -eq "$Wc_c" || echo 'xdtm/parse.h: original size 2063, current size' "$Wc_c" fi # ============= xdtm/parser.y ============== if test -f 'xdtm/parser.y' -a X"$1" != X"-c"; then echo 'x - skipping xdtm/parser.y (File already exists)' else echo 'x - extracting xdtm/parser.y (Text)' sed 's/^X//' << 'SHAR_EOF' > 'xdtm/parser.y' && X%{ /*-*- Mode: C -*-*/ X/************************************************************************** X ** Filename : parser.y ** X ** Author : Edward Groenendaal ** X ** Date : 31/1/91 ** X ** Purpose : Parse the xdtm config file, build the data ** X ** structures. ** X **************************************************************************/ X X#define YYDEBUG 1 /* allow yacc debugging */ X#include "xdtm.h" X#include "parse.h" X X#if defined(sco386) && defined(M_INTERNAT) /* jcc */ X#undef M_INTERNAT X#endif X X#include <regexp.h> /* Needed for regular expression compilation */ X X/* structure used to hold loaded bitmaps (pixmaps), the pixmaps referenced X * in the icon list are pointing into this structure. X */ Xtypedef struct _iconTree { X String fullname; /* index on this */ X Pixmap icon; X struct _iconTree *left; X struct _iconTree *right; X} iconTree; X X/* The variable stack frame, this stack holds the stack frames for use in X * calculating the scope of local variables in the config language. X */ Xtypedef struct _varStack { X String *defpath; /* path in this stack */ X Cardinal dirinpath; /* Number of dirs in path */ X Boolean checkpath; /* Whether to match over the whole path */ X iconPrefs *iconpref; /* The point into the main icon structure X * at which this frame's results will be X * inserted. X */ X typePrefs *current; /* The level at which the new iconprefs X * will be inserted. X */ X struct _varStack *next; /* Next link in stack */ X} varStack; X X/* Declarations of procedures defined after they have been referenced */ Xpublic typePrefs *newTypePref(void); Xprivate void start_block(typePrefs*,iconPrefs*); Xprivate void end_block(void); Xprivate String *stringtopath(String, Cardinal*); Xprivate Pixmap lookupicon(String); Xprivate iconPrefs *getlast(iconPrefs*); Xprivate iconPrefs *inserticonpref(iconPrefs*, iconPrefs*); Xprivate String strip_quotes(String); Xprivate iconTree *get_pixmap(iconTree*,iconTree*); Xprivate void set_path(String); Xprivate void set_icon(String, Boolean); Xprivate void set_deficon(String); Xprivate void set_ignore(void); Xprivate void newselection(String); Xprivate void setapp(int, String); X X/* imported variables/procedures */ Xextern int parseerror; /* quantity of parse errors so far */ Xextern int yylineno; /* line number being parsed */ Xextern void yyerror(char *, ...); /* normal error printing routine */ X X#ifndef DEBUG_YACC Xextern Widget topLevel; X#endif X X/* Variable declarations */ Xpublic AppSelection **appselections; Xpublic typePrefs *prefs; /* preferneces */ Xprivate varStack *varframe; /* stack frames */ Xprivate iconTree *icontable; /* table of pixmaps */ Xprivate char *ptr; /* general use pointer */ Xprivate AppSelection *current_selection; Xprivate Cardinal listindex; /* index into current appprogram list */ Xprivate Cardinal currentlistmax; /* current list appprogram size */ Xpublic Cardinal selectionindex; /* index into appselections */ X X%} /* Start of YACC declarations */ X X%start xdtmrc X X%union /* valid types */ X{ X int number; /* number */ X char *string; /* string */ X} X X/* declare terminals with their types */ X X%token <string> STRING_T X%token <number> IF_T SET_T ICON_T NAME_T PATH_T DEFICON_T TYPE_T CHECKPATH_T X%token <number> TRUE_T FALSE_T IGNORE_T X%token <number> DIR_T FILE_T READ_T WRITE_T EXE_T BLOCK_T CHARACTER_T SLINK_T X%token <number> SOCKET_T FIFO_T X%token <number> MSEL_T OSEL_T NSEL_T DEFINE_T PROG_T OPTIONS_T X%token <number> ASSIGN_T EQUAL_T SEMIC_T COMMA_T X%token <number> O_PAR_T C_PAR_T O_BRACE_T C_BRACE_T X%token <value> EOFTOKEN ERRORTOKEN X X/* types of non-terminals */ X%type <string> identifier X%type <number> block type var option xdtmrc X X%% /* Beginning of rule section */ X Xxdtmrc : { init_structs(); } X statements X { free_structs(); } X ; Xstatements : /* Empty */ X | statements statement X ; Xstatement : ifstatement X | setstatement SEMIC_T X | define X ; Xifstatement : IF_T O_PAR_T expression C_PAR_T block X ; Xsetstatement : SET_T var ASSIGN_T identifier { switch ($2) { X case PATH_T: X set_path($4); X break; X case ICON_T: X set_icon($4, False); X break; X case DEFICON_T: X set_deficon($4); X break; X } X } X | SET_T CHECKPATH_T ASSIGN_T TRUE_T X { varframe->checkpath = True; } X | SET_T CHECKPATH_T ASSIGN_T FALSE_T X { varframe->checkpath = False; } X | SET_T IGNORE_T X { set_icon("", True);} X ; Xdefine : DEFINE_T identifier {newselection($2);} ASSIGN_T defineblock X ; Xblock : O_BRACE_T X statements {end_block();} X C_BRACE_T X ; Xdefineblock : O_BRACE_T descriptions C_BRACE_T X {current_selection->number = listindex;} X ; Xdescriptions : /* Empty */ X | descriptions description X ; Xdescription : O_BRACE_T X X { /* Allocate a new AppProgram */ X X current_selection->list[listindex] = X (AppProgram*) XtMalloc (sizeof(AppProgram)); X } X X NAME_T ASSIGN_T identifier SEMIC_T {setapp($3, $5);} X ICON_T ASSIGN_T identifier SEMIC_T {setapp($8, $10);} X PROG_T ASSIGN_T identifier SEMIC_T {setapp($13, $15);} X OPTIONS_T ASSIGN_T option SEMIC_T X { X setapp($18, (String)$20); X X /* Increment listindex, Thanks to Johan Widen for catching X * a bug here in version 1.0. X */ X if (++listindex == currentlistmax) { X currentlistmax += APPPINC; X current_selection->list = X (AppProgram**) XtRealloc (current_selection->list, X sizeof(AppProgram*) * X currentlistmax); X } X } X X C_BRACE_T X ; Xoption : MSEL_T | OSEL_T | NSEL_T X ; Xexpression : NAME_T EQUAL_T identifier { new_re($3); } X | TYPE_T EQUAL_T type { new_type($3); } X ; Xidentifier : STRING_T { $$=strip_quotes($1); X } X ; Xtype : DIR_T | READ_T | WRITE_T | EXE_T | FILE_T | X BLOCK_T | CHARACTER_T | FIFO_T | SLINK_T | SOCKET_T X ; Xvar : PATH_T | ICON_T | DEFICON_T X ; X%% X X/***************************************************************************** X * init_structs * X *****************************************************************************/ Xprivate void init_structs(void) X{ X /* Initialise structures.. wow what a suprise :-) */ X X Cardinal n; X X /* Icon prefs = an empty type pref */ X prefs = newTypePref(); X X /* Icon table is empty, no icons loaded yet */ X icontable = NULL; X X /* Default top level stack frame */ X varframe = (varStack*) XtMalloc (sizeof(varStack)); X varframe->defpath = stringtopath("/usr/lib/X11/bitmaps", &n); X varframe->dirinpath = n; X varframe->current = prefs; X varframe->checkpath = False; X varframe->iconpref = NULL; X varframe->next = NULL; X X /* initialise the Application Selection Lists Array */ X listindex = 0; /* First entry in the new selection list */ X selectionindex = -1; /* First selection list is 0 in the array */ X appselections = (AppSelection**) XtMalloc (sizeof(AppSelection*) * APPPSIZE); X} X X/***************************************************************************** X * free_structs * X *****************************************************************************/ Xprivate void free_structs(void) X{ X /* This procedure is called just before the parsing finishes, it free's X * the memory allocated to the internal structures used by the parser. X * Note: Doesn't get all of them.. but let's not get petty, what's a few X * bytes once only in a program of this size? X */ X X /* Free varstack (Should be only one level left) */ X XtFree(varframe); X X selectionindex++; /* So that we know the correct number of selections */ X} X X/***************************************************************************** X * newTypePref * X *****************************************************************************/ Xpublic typePrefs *newTypePref(void) X{ X /* Allocate the memory for a new empty typePref, I suppose this X * procedure is not really needed on most machines, but what if X * a machine doesn't automatically fill all entries in a structure X * with NULL's ? X */ X X typePrefs *tp; X X tp = (typePrefs*) XtMalloc (sizeof(typePrefs)); X tp->iconprefs = NULL; X tp->dir = NULL; X tp->file = NULL; X tp->block = NULL; X tp->character = NULL; X tp->fifo = NULL; X tp->slink = NULL; X tp->socket = NULL; X tp->exe = NULL; X tp->read = NULL; X tp->write = NULL; X X return(tp); X} X X/***************************************************************************** X * start_block * X *****************************************************************************/ Xprivate void start_block(typePrefs *newpref, iconPrefs *iconpref) X{ X /* A new block has been entered, create a new stack frame, inherit most X * stuff from the previous stack frame. X */ X X /* Push new stack frame */ X varStack *newframe; X X newframe = (varStack*) XtMalloc (sizeof(varStack)); X newframe->defpath = varframe->defpath; X newframe->dirinpath = varframe->dirinpath; X newframe->current = newpref; X newframe->checkpath = varframe->checkpath; X newframe->iconpref = iconpref; X newframe->next = varframe; X varframe = newframe; X} X X/***************************************************************************** X * end_block * X *****************************************************************************/ Xprivate void end_block(void) X{ X /* End the current stack frame, check to see if the extra part of X * the iconPref has been used, if not free it. X * Pop the current stack from off the stack. X */ X X iconPrefs *tmpIconPref; X typePrefs *tmp = varframe->current; X varStack *tmpframe = varframe->next; X X if (tmp->iconprefs == NULL && tmp->dir == NULL && X tmp->file == NULL && tmp->exe == NULL && X tmp->read == NULL && tmp->write == NULL) { X XtFree(tmp); X tmp = NULL; X tmpIconPref = varframe->iconpref; X tmpIconPref->extra = NULL; X } X XtFree(varframe); X varframe = tmpframe; X} X X/***************************************************************************** X * new_re * X *****************************************************************************/ Xprivate void new_re(String re) X{ X /* Create a new iconpref, put the compiled regular expression in it then X * insert it into the current iconprefs. X * X * - Takes a regular expression in the original string format. eg. "\.c$" X */ X X iconPrefs *new, *tmp = varframe->current->iconprefs; X X new = (iconPrefs*) XtMalloc (sizeof(iconPrefs)); X new->next = NULL; X new->expbuf = (char*) XtMalloc (sizeof(char) * ESIZE); X new->extra = (XtPointer) newTypePref(); X compile(re, new->expbuf, &(new->expbuf[ESIZE]), '\0'); X new->circf = circf; X new->checkpath = varframe->checkpath; X new->icon = NULL; X varframe->current->iconprefs = inserticonpref(tmp, new); X start_block((typePrefs*)new->extra, (iconPrefs*)new); X} X X/***************************************************************************** X * new_type * X *****************************************************************************/ Xprivate void new_type(int n) X{ X /* Allocate a typePref on dir, write etc. if neadbe, otherwise ignore X * X * - Takes a number representing which file feature to insert the typePref X * on. X */ X X typePrefs *typeprefs = varframe->current; X typePrefs *newpref; X X switch(n) { X case DIR_T: X if (typeprefs->dir == NULL) X typeprefs->dir = newTypePref(); X newpref = typeprefs->dir; X break; X case FILE_T: X if (typeprefs->file == NULL) X typeprefs->file = newTypePref(); X newpref = typeprefs->file; X break; X case BLOCK_T: X if (typeprefs->block == NULL) X typeprefs->block = newTypePref(); X newpref = typeprefs->block; X break; X case CHARACTER_T: X if (typeprefs->character == NULL) X typeprefs->character = newTypePref(); X newpref = typeprefs->character; X break; X case FIFO_T: X if (typeprefs->fifo == NULL) X typeprefs->fifo = newTypePref(); X newpref = typeprefs->fifo; X break; X case SLINK_T: X if (typeprefs->slink == NULL) X typeprefs->slink = newTypePref(); X newpref = typeprefs->slink; X break; X case SOCKET_T: X if (typeprefs->socket == NULL) X typeprefs->socket = newTypePref(); X newpref = typeprefs->socket; X break; X case EXE_T: X if (typeprefs->exe == NULL) X typeprefs->exe = newTypePref(); X newpref = typeprefs->exe; X break; X case READ_T: X if (typeprefs->read == NULL) X typeprefs->read = newTypePref(); X newpref = typeprefs->read; X break; X case WRITE_T: X if (typeprefs->write == NULL) X typeprefs->write = newTypePref(); X newpref = typeprefs->write; X break; X } X start_block(newpref, NULL); X} X X/***************************************************************************** X * count_chr * X *****************************************************************************/ Xpublic Cardinal count_chr(String s, char c) X{ X /* Given a String and a character this function counts the number of X * occurences of that character in the string and returns the result. X * X * - Takes a string s within which to check for character c. X */ X X Cardinal count=0; X X while(*s != '\0') { X if (*s == c) count++; X s++; X } X return count; X} X X/***************************************************************************** X * stringtopath * X *****************************************************************************/ Xprivate String *stringtopath(String s, Cardinal *n) X{ X /* Split a path into directories, put these into a linked list X * only directories starting with / or ~/ are allowed. X * X * - Takes a string containing the path delimited by colons, and X * a pointer within which the number of directories in the X * path is left. X * + Returns an array of directories. X */ X String *result; X String p, tmp; X#ifdef DEBUG_YACC X String home; X#else X extern String home; X#endif X X *n = 0; X X#ifdef DEBUG_YACC X if ((home = (String) getenv("HOME")) == NULL) { X fprintf(stderr, "can\'t get environment variable HOME\n"); X home = XtNewString("/"); X } else X home = XtNewString(home); X#endif X X result = (String*) XtMalloc ((count_chr(s, ':')+3) * sizeof(String)); X s = XtNewString(s); X X /* extract the directories from path 's' */ X X p = strtok(s, ":"); X while ( p != NULL) { X if (*p == '/') X result[(*n)++] = p; X else X if (*p == '~' && *(p+1) == '/') { X tmp = (String) XtMalloc ((strlen(home) + strlen(p) + 2) * sizeof(char)); X strcpy(tmp, home); X strcat(tmp, p+1); X result[(*n)++] = tmp; X } else X fprintf(stderr, "Warning: Directory \'%s\' not fully qualified," X " ignoring.\n" X " Must start with either / or ~/ .\n", p); X p = strtok(NULL, ":"); X } X#ifdef DEBUG_YACC X XtFree(home); X#endif X return(result); X} X X/***************************************************************************** X * inserticonpref * X *****************************************************************************/ Xprivate iconPrefs *inserticonpref(iconPrefs *head, iconPrefs *item) X{ X /* Insert item into list starting with head, insert into the last X * position before the default. X * X * - Takes the head of the iconpref list and the iconpref list entry to X * be inserted. X * + Returns the new iconpref list with the item inserted. X */ X X iconPrefs *sec = NULL, *tmp = head; X X if (head == NULL) { X /* first element */ X head=item; X head->next=NULL; X } else { X while (tmp->next != NULL) { X sec = tmp; X tmp = tmp->next; X } X if (tmp->expbuf == NULL) { X /* Already got a default */ X if (item->expbuf != NULL) { X /* Item is not a new default */ X item->next = tmp; X if (sec != NULL) X sec->next = item; X else X head = item; X } else X XtFree(item); X } else { X /* No default */ X tmp->next = item; X item->next = NULL; X } X } X return(head); X} X X/***************************************************************************** X * getlast * X *****************************************************************************/ Xprivate iconPrefs *getlast(iconPrefs *head) X{ X /* return the last non-default iconpref in the frame X * X * - Takes the head of the iconpref list X * + Returns the last non-default iconpref in that iconpref list X */ X X iconPrefs *tmp = head; X X if (tmp != NULL) X while (tmp->next != NULL || tmp->next->expbuf == NULL) X tmp = tmp->next; X X return(tmp); X} X X/***************************************************************************** X * strip_quotes * X *****************************************************************************/ Xprivate String strip_quotes(String s) X{ X /* This function is for stripping the first and last characters from a X * string. It is used for stripping the quotes off strings. X * X * - Takes a String with quotes. X * - Returns the String with quotes missing. X */ X String new; X X *(s + (strlen(s)-1)) = '\0'; X s=s+1; X new = XtNewString(s); X X /* s is NOT free'd because it was supplied from the lexical analyzer, X * it's up to that to free it. X */ X return(new); X} X X/***************************************************************************** X * set_path * X *****************************************************************************/ Xprivate void set_path(String s) X{ X /* Given a string containing a list of directories delimited by colons X * this procedure inserts these directories in teh form of an array of X * strings into the current stack frame. X */ X Cardinal n; X X varframe->defpath = stringtopath(s, &n); X varframe->dirinpath = n; X} X X/***************************************************************************** X * set_icon * X *****************************************************************************/ Xprivate void set_icon(String s, Boolean ignore) X{ X /* varframe->iconpref points to the iconpref into which this X * icon should be inserted. If it is NULL, then create a new X * one at varframe->current->iconprefs. X * X * - Takes an icon filename and/or a flag saying whether the current X * iconpref should be ignored. X */ X X typePrefs *frame = varframe->current; X iconPrefs *iconpref = varframe->iconpref, X *head = frame->iconprefs, X *new = NULL; X X if (iconpref == NULL) { X new = (iconPrefs*) XtMalloc (sizeof(iconPrefs)); X new->expbuf = NULL; /* default icon */ X new->extra = NULL; X if (ignore==True) { X new->icon = DUMMY; X } else { X new->icon = lookupicon(s); X } X new->next = NULL; X frame->iconprefs = inserticonpref(head, new); X } else X if (ignore==True) X iconpref->icon = DUMMY; X else X iconpref->icon = lookupicon(s); X X} X X/***************************************************************************** X * set_deficon * X *****************************************************************************/ Xprivate void set_deficon(String s) X{ X /* Set the default icon in the current iconprefs list. X * X * - Takes the filename of the icon to be used. X */ X X typePrefs *frame = varframe->current; X iconPrefs *iconpref, *head = frame->iconprefs; X X iconpref = (iconPrefs*) XtMalloc (sizeof(iconPrefs)); X iconpref->expbuf = NULL; /* default icon */ X iconpref->extra = NULL; X iconpref->icon = lookupicon(s); X iconpref->next = NULL; X frame->iconprefs = inserticonpref(head, iconpref); X X} X X/***************************************************************************** X * lookupicon * X *****************************************************************************/ Xprivate Pixmap lookupicon(String icon) X{ X /* Return the pixmap associated with the name 'icon' if none X * found NULL is returned. X */ X X typePrefs *frame = varframe->current; X String *path = varframe->defpath; X Cardinal pathsize = varframe->dirinpath; X Cardinal n; X iconTree *item; X Pixmap pixmap = NULL; X String fullname = NULL; X String tmp; X FILE *result; X X /* Append 'icon' to each filename in current path, and check to see X * whether that file exists. X */ X X n = 0; X do { X tmp = (String) XtMalloc ((strlen(icon) + strlen(path[n]) + 4) * sizeof(char)); X tmp = strcpy(tmp, path[n]); X tmp = strcat(tmp, "/"); X tmp = strcat(tmp, icon); X if ((result = fopen(tmp, "r")) != NULL) { X fullname = XtNewString(tmp); X fclose(result); X } X XtFree(tmp); X } while (++n < pathsize && fullname == NULL); X X if (fullname == NULL) X fprintf(stderr, "Warning: could not find icon %s," X " default icon will be used instead.\n", icon); X else { X item = (iconTree*) XtMalloc (sizeof(iconTree)); X item->fullname = fullname; X item->icon = NULL; X icontable = get_pixmap(item, icontable); X pixmap = item->icon; X } X return(pixmap); X} X X/***************************************************************************** X * get_pixmap * X *****************************************************************************/ Xprivate iconTree *get_pixmap(iconTree *item, iconTree *tree) X{ X /* If the item is found in the tree, then item's contents are filled X * with that items, otherwise the Pixmap is created and the item is X * inserted into the tree. X */ X X int cmp, value; X unsigned int width, height; X int x_hot, y_hot; X X if (tree == NULL) { X /* At a leaf, insert item */ X#ifndef DEBUG_YACC X value = XReadBitmapFile(XtDisplay(topLevel), X RootWindowOfScreen(XtScreen(topLevel)), X item->fullname, X &width, &height, X &item->icon, X &x_hot, &y_hot); X if (value == BitmapFileInvalid) X fprintf(stderr, "Filename \'%s\' contains invalid bitmap data\n", X item->fullname); X else if (value == BitmapOpenFailed) X fprintf(stderr, "Filename \'%s\' could not be opened\n", X item->fullname); X else if (value == BitmapNoMemory) X fprintf(stderr, "Not enough memory to allocate pixmap\n"); X#else X item->icon = (Pixmap) DUMMY; X printf("DEBUG: Loaded bitmap for %s\n", item->fullname); X#endif X item->left = NULL; X item->right = NULL; X tree = item; X } else { X if ((cmp = strcmp(tree->fullname, item->fullname)) == 0) { X /* Found it !!! */ X item->icon = tree->icon; X } else X if (cmp < 0) X tree->left = get_pixmap(item, tree->left); X else X tree->right = get_pixmap(item, tree->right); X } X return(tree); X} X X/***************************************************************************** X * newselection * X *****************************************************************************/ Xprivate void newselection(String selection) X{ X /* increment selectionindex, put selection string into next X * appselection, increase size if appselections array if needed. X * X * - Takes the name of the new selection X */ X X static selectionmax = APPPSIZE; X X if (++selectionindex == selectionmax) { X selectionmax += APPPINC; X appselections = (AppSelection **) XtRealloc (appselections, X sizeof(AppSelection*) * X selectionmax); X } X X#ifdef DEBUG_YACC X printf("DEBUG: New selection %s\n", selection); X#endif X X listindex = 0; X current_selection = appselections[selectionindex] = X (AppSelection*) XtMalloc (sizeof(AppSelection)); X current_selection->name = XtNewString(selection); X current_selection->number = listindex; X current_selection->list = (AppProgram**) XtMalloc (sizeof(AppProgram*) * X APPPSIZE); X currentlistmax = APPPSIZE; X} X X/***************************************************************************** X * setapp * X *****************************************************************************/ Xprivate void setapp(int type, String argument) X{ X /* Set part of the current program in the current selection list, X * the part to be set is contained in type, the value it is to be set X * to contained within argument. X */ X X AppProgram **proglist = current_selection->list; X AppProgram *node = proglist[listindex]; X X switch(type) { X case NAME_T: X node->string = XtNewString(argument); X#ifdef DEBUG_YACC X printf("String: %s\n", argument); X#endif X break; X case ICON_T: X node->icon = lookupicon(argument); X break; X case PROG_T: X node->program = XtNewString(argument); X#ifdef DEBUG_YACC X printf("Program: %s\n", argument); X#endif X break; X case OPTIONS_T: X switch((int)argument) { X case MSEL_T: X node->options = M_SEL; X#ifdef DEBUG_YACC X printf("MSEL\n"); X#endif X break; X case OSEL_T: X node->options = O_SEL; X#ifdef DEBUG_YACC X printf("OSEL\n"); X#endif X break; X case NSEL_T: X node->options = N_SEL; X#ifdef DEBUG_YACC X printf("NSEL\n"); X#endif X break; X default: X fprintf(stderr, "Programmer Error: Bad argument to setapp.\n"); X break; X } X break; X default: X fprintf(stderr, "Programmer Error: Bad argument to setapp.\n"); X break; X } X} X X#ifdef DEBUG_YACC X X/***************************************************************************** X * main * X *****************************************************************************/ Xmain() X{ X /* main for use when the real main is not linked, because we in debug mode. X */ X X yyparse(); /* Parse the stdin */ X return(0); /* Hey, it probably worked */ X} X#endif X X X X SHAR_EOF chmod 0644 xdtm/parser.y || echo 'restore of xdtm/parser.y failed' Wc_c="`wc -c < 'xdtm/parser.y'`" test 27319 -eq "$Wc_c" || echo 'xdtm/parser.y: original size 27319, current size' "$Wc_c" fi true || echo 'restore of xdtm/patchlevel.h failed' echo End of part 10, continue with part 11 exit 0 -- Dan Heller O'Reilly && Associates Z-Code Software Comp-sources-x: Senior Writer President comp-sources-x@uunet.uu.net argv@ora.com argv@zipcode.com