/* * C4 -- CVS like front end to the Perforce p4 SCM tool. * * Copyright (c) 1998 - 2003, 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 not 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. * * Command execution. */ #include "defs.h" /**************************************************/ /* * Command invocation. */ int CmdArgs; /* Number of args seen */ int CmdExec = 1; /* '-n' ommand line option */ char * CmdP4 = "p4"; /* Name of the real p4 command */ static char * cmd; /* Command string under construction */ static int cmd_index; /* Next available argument */ static int cmd_base; /* First argument of xargs list */ static int cmd_size; /* Available argument space */ static int cmd_clobber; /* Command changes things */ static void (*cmd_func)(char *); /* Output processing function */ void Command(char * c, void (*f)(char *), int clobber) { /* * Calculate the size of the argument space. */ if (!cmd) { char ** ep; extern char ** environ; cmd_size = NCARGS - 4 * 1024; for (ep = environ; *ep; ep++) cmd_size -= strlen(*ep) + 1 + sizeof (*ep); if (cmd_size > 32768) cmd_size = 32768; cmd = Alloc(cmd_size); } /* * Copy the initial command string into the arg string (we * assume that the command string will fit in the available * argument space). */ strcpy(cmd, CmdP4); strcat(cmd, " "); strcat(cmd, c); cmd_index = strlen(cmd); cmd_base = cmd_index; cmd_func = f; cmd_clobber = clobber; CmdArgs = 0; } void CommandDone(void) { FILE * fd; char line[1024]; if (Debug >= 1) printf("\t%s\n", cmd); if (cmd_clobber && !CmdExec) return; if (!cmd_func) system(cmd); else { fd = popen(cmd, "r"); if (!fd) { cmd[cmd_base] = '\0'; Error(1, "Can't popen command (%.40s)", cmd); } while (fgets(line, sizeof line, fd)) { char * nl; if (nl = strchr(line, '\n')) *nl = '\0'; (*cmd_func)(line); } pclose(fd); } } /* * Copy the string `src' to `dst' with quotes added as necessary. * We decide to add quotes conservatively -- a string which has * any characters other than [A-Za-z0-9+-_/.] will have quotes added. * Returns the number of characters placed in `dst'; if `dst' is * NIL, the scan still takes place, but no data is stored. A '\0' * is appended but is not counted. */ static int command_char(char * dst, char * src) { char * d; char * s; int quote; int chr; quote = 0; again: d = dst; s = src; if (quote) { if (dst) *d = '"'; d++; } while ((chr = *s++)) { if (quote == 0 && (chr < 'A' || chr > 'Z') && (chr < 'a' || chr > 'z') && (chr < '0' || chr > '9') && chr != '+' && chr != '-' && chr != '_' && chr != '/' && chr != '.') { quote = 1; goto again; } if (chr == '$' || chr == '`' || chr == '\\' || chr == '"' || chr == '\n') { if (dst) *d = '\\'; d++; } if (dst) *d = chr; d++; } if (quote) { if (dst) *d = '"'; d++; } if (dst) *d = '\0'; return d - dst; } void CommandArg(char * a) { int l; l = command_char((char *)0, a); if (cmd_index + 1 + l + 1 > cmd_size) { CommandDone(); cmd_index = cmd_base; } strcpy(&cmd[cmd_index++], " "); (void)command_char(&cmd[cmd_index], a); cmd_index += l; CmdArgs++; }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 3624 | Mitch Stuart | Branch //public/perforce/utils to //guest/mitch_stuart/perforce/utils | ||
//guest/perforce_software/utils/c4/command.c | |||||
#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 |