/* ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 1, or (at your option) ** any later version. ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Author : Alexandre Parenteau --- December 1997 */ /* * CvsArgs.cpp --- class to handle cvs arguments */ #include "stdafx.h" #include #include #include "CvsPrefs.h" #include "CvsArgs.h" #include "AppConsole.h" #include "Authen.h" #ifdef WIN32 # ifdef _DEBUG # define new DEBUG_NEW # undef THIS_FILE static char THIS_FILE[] = __FILE__; # endif #endif /* WIN32 */ static char *mystrdup(const char *string) { int size = strlen(string); char *result = (char *)malloc((size + 1) * sizeof(char)); if(result == NULL) { cvs_err("Impossible to allocate %d bytes !\n", size + 1); exit(1); } strcpy(result, string); return result; } CvsArgs::CvsArgs(bool defargs) { argv = NULL; argc = 0; reset(defargs); } CvsArgs::CvsArgs(char * const *fromargv, int fromargc) { argv = NULL; argc = 0; reset(false); for(int i = 0; i < fromargc; i++) { add(fromargv[i]); } } CvsArgs::~CvsArgs() { reset(false); } void CvsArgs::reset(bool defargs) { if(argv != 0L) { for(int i = 0; i < argc; i++) { if(argv[i] != 0L) free(argv[i]); } free(argv); } argc = 0; argv = NULL; if(defargs) { int numargs = 1; if(gCvsPrefs.Z9Option()) numargs++; if(gCvsPrefs.QuietOption()) numargs++; if(gCvsPrefs.EncryptCommunication() && gAuthen.kind() == gserver) numargs++; if(gCvsPrefs.AlwaysUseCvsroot()) numargs += 2; argv = (char **)malloc(numargs * sizeof(char *)); argv[argc++] = mystrdup("cvs"); if(gCvsPrefs.AlwaysUseCvsroot()) { argv[argc++] = mystrdup("-d"); CStr root; const char *ccvsroot = gCvsPrefs; ccvsroot = Authen::skiptoken(ccvsroot); root = gAuthen.token(); root << ccvsroot; argv[argc++] = mystrdup(root); } if(gCvsPrefs.Z9Option()) { CStr zlev("-z"); zlev << gCvsPrefs.ZLevel(); argv[argc++] = mystrdup(zlev); } if(gCvsPrefs.QuietOption()) argv[argc++] = mystrdup("-q"); if(gCvsPrefs.EncryptCommunication() && gAuthen.kind() == gserver) argv[argc++] = mystrdup("-x"); } } // reduce a long string for printing, add "..." if the length // is up the limit #define MAX_PRINT_ARG 80 static char *reduceString(const char *str, CStaticAllocT & buf) { buf.AdjustSize(MAX_PRINT_ARG + 4); // "..." + '\0' size_t len = strlen(str); if(len < MAX_PRINT_ARG) { strcpy(buf, str); } else { memcpy((char *)buf, str, MAX_PRINT_ARG * sizeof(char)); char *tmp = (char *)buf + MAX_PRINT_ARG; *tmp++ = '.'; *tmp++ = '.'; *tmp++ = '.'; *tmp = '\0'; } return buf; } // replace \n by "\n" so it's readable static char *expandLF(const char *str, CStaticAllocT & buf) { int numLFs = 0; const char *runner = str; while((runner = strchr(runner, '\n')) != 0L) { numLFs++; runner++; } size_t len = strlen(str); buf.AdjustSize(len + numLFs + 1); // numLFs * "\n" + '\0' char *tmp = buf; char c; runner = str; while((c = *runner++) != '\0') { if(c == '\n') { *tmp++ = '\\'; *tmp++ = 'n'; } else *tmp++ = c; } *tmp++ = '\0'; return buf; } static CStaticAllocT buf; void CvsArgs::print(const char *indirectory) { static CStaticAllocT buf; for(int i = 0; i < argc; i++) { CStr newarg; newarg = argv[i]; bool hasLF = strchr(newarg, '\n') != 0L; size_t len = newarg.length(); if(len > MAX_PRINT_ARG) newarg = reduceString(newarg, buf); if(hasLF) newarg = expandLF(newarg, buf); bool hasSpace = strchr(newarg, ' ') != 0L; if(hasSpace) cvs_out("\""); cvs_outstr(newarg, newarg.length()); if(hasSpace) cvs_out("\""); cvs_out(" "); } if(indirectory != NULL) cvs_out("(in directory %s)", indirectory); cvs_out("\n"); } void CvsArgs::add(const char *arg) { if(argv == 0L) argv = (char **)malloc(2 * sizeof(char *)); else argv = (char **)realloc(argv, (argc + 2) * sizeof(char *)); argv[argc++] = arg != 0L ? mystrdup(arg) : 0L; argv[argc] = 0L; } void CvsArgs::addfile(const char *arg, const char * /*dir*/, const UFSSpec * /*spec*/, const char* /*currRevision*/) { add(arg); }