/* * C4 -- CVS like front end to the Perforce p4 SCM tool. * * Copyright (c) 1997, Neil Russell. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Neil Russell. * 4. The name Neil Russell may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY NEIL RUSSELL ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NEIL RUSSELL BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Ignored file processing. */ #include "defs.h" #include <errno.h> Ignore * gbl_ignore; /**************************************************/ /* * Setup global ignore file specifications. */ void IgnoreSpec(Ignore ** ilpp, char * spec) { char * cp; Ignore * ilp; /* * Remove suronding spaces */ while (*spec == ' ' || *spec == '\t') spec++; for ( cp = spec + strlen(spec) - 1; cp >= spec && (*cp == ' ' || *cp == '\t'); ) *cp-- = '\0'; if (!ilpp) ilpp = &gbl_ignore; if (*spec == '\0') { /* * Null spec means kill the list. */ for (ilp = *ilpp; ilp; ) { Ignore * xp; if (ilp->spec) free(ilp->spec); xp = ilp->next; free(ilp); ilp = xp; } *ilpp = (Ignore *)0; return; } ilp = (Ignore *)Alloc(sizeof (Ignore)); ilp->spec = (char *)Alloc(strlen(spec) + 1); strcpy(ilp->spec, spec); ilp->next = *ilpp; *ilpp = ilp; } /**************************************************/ /* * Read a ignore file from the local directory. */ static void read_ignore_file(char * dir, File * dp) { int fd; char * p1; char * p2; int x; char name[1024]; char specs[4096]; extern int errno; if (dp->flag & F_IGNORELIST) return; dp->flag |= F_IGNORELIST; strcpy(name, dir); strcat(name, "/" C4IGNORE); if ((fd = open(name, O_RDONLY)) == -1) { if (errno != ENOENT) Error(1, "cannot open %s", name); return; } /* * Read the file. The amount of stuff in this * file is limited to 4KB (sizeof specs) at the * moment. There is currently no need for more. */ x = read(fd, specs, sizeof specs - 1); if (x == -1) Error(1, "read error on %s", name); if (x == sizeof specs - 1) Error(0, "contents of file %s is too long (%d byte limit)", name, sizeof specs); specs[x] = '\0'; close(fd); for (p1 = specs; (p2 = strchr(p1, '\n')); ) { char * xp; *p2 = '\0'; IgnoreSpec(&dp->ignore, p1); p1 = p2 + 1; } } /**************************************************/ /* * Return true if the given file name matches a spec on the * given spec list. If the given name has path components, * match only the last component. Shell like globbing is * used. * * This code was lifted from the FreeBSD /bin/sh file expand.c, * and slightly modified (CTLESC and collation removed -- * ASCII only and no escaped control characters). */ /* * Copyright (c) 1985, 1987, 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ static int glob(char * spec, char * name) { char c; for (;;) { switch (c = *spec++) { case '\0': goto breakloop; case '?': if (*name++ == '\0') return 0; break; case '*': c = *spec; if (c != '?' && c != '*' && c != '[') { while (*name != c) { if (*name == '\0') return 0; name++; } } do { if (glob(spec, name)) return 1; } while (*name++ != '\0'); return 0; case '[': { char * endp; int invert; int found; char chr; endp = spec; if (*endp == '!') endp++; for (;;) { if (*endp == '\0') { /* no matching ] */ goto dft; } if (*++endp == ']') break; } invert = 0; if (*spec == '!') { invert++; spec++; } found = 0; chr = *name++; if (chr == '\0') return 0; c = *spec++; do { if (*spec == '-' && spec[1] != ']') { spec++; if (chr >= c && chr <= *spec) found = 1; spec++; } else { if (chr == c) found = 1; } } while ((c = *spec++) != ']'); if (found == invert) return 0; break; } default: dft: if (*name++ != c) return 0; break; } } breakloop: if (*name != '\0') return 0; return 1; } static int is_ignored(Ignore * ilp, char * name) { for (; ilp; ilp = ilp->next) { if (glob(ilp->spec, name)) return 1; } return 0; } /**************************************************/ /* * Set up the initial global ignore list. */ static void init_ignore(void) { static int beenhere = 0; if (beenhere) return; beenhere = 1; IgnoreSpec((Ignore **)0, "*.o"); IgnoreSpec((Ignore **)0, "*.a"); IgnoreSpec((Ignore **)0, "*.Z"); IgnoreSpec((Ignore **)0, "*.gz"); IgnoreSpec((Ignore **)0, ".c4"); IgnoreSpec((Ignore **)0, "tags"); IgnoreSpec((Ignore **)0, "TAGS"); IgnoreSpec((Ignore **)0, "core"); } /**************************************************/ /* * Ignored file detection. */ int IsIgnored(char * dir, File * dp, char * name) { init_ignore(); read_ignore_file(dir, dp); return (is_ignored(dp->ignore, name) || is_ignored(gbl_ignore, name)); }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#4 | 3458 | Neil Russell |
C4: * Updated from 1.6 to 1.10. Changes include: - Fixed handling of file names with spaces. - Improved igmore list handling. - Other miscelaneous fixes. |
||
#3 | 276 | Neil Russell |
C4 - small bug fixed; updated to version 1.6 * We are now a little more intelligent about what happens if there is a merge conflict between the local client and the head of the tree, and also about trying to do a refresh and a sync on the same file. |
||
#2 | 159 | Neil Russell |
C4 integrated into //public/perforce/utils/c4. This is version 1.4 of C4, ready for release. |
||
#1 | 18 | Perforce maintenance | Add c4, a CVS-like frontend to p4 |