Chapter 3
Public Methods Reference
ClientApi methods
ClientApi::DefineClient( const char *, Error * )
Sets P4CLIENT in the Windows registry and applies the setting immediately.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const char* c - the new P4CLIENT setting Error* e - an Error object
|
Returns
|
void
|
Notes
To make the new P4CLIENT setting apply to the next command executed with Run(), DefineClient() sets the value in the registry and then calls SetClient().
Example
The following code illustrates how this method might be used to make a Windows client application start up with a default P4CLIENT setting.
|
client.Init( &e ); client.DefineClient("default_workspace", &e);
|
ClientApi::DefineHost( const char *, Error * )
Sets P4HOST in the Windows registry and applies the setting immediately.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const char* c - the new P4HOST setting Error* e - an Error object
|
Returns
|
void
|
Notes
To make the new P4HOST setting apply to the next command executed with Run(), DefineHost() sets the value in the registry and then calls SetHost().
Example
The following code illustrates how this method might be used to make a Windows client application start up with a default P4HOST setting.
|
client.Init( &e ); client.DefineHost("default_host", &e);
|
ClientApi::DefinePassword( const char *, Error * )
Sets P4PASSWD in the Windows registry and applies the setting immediately.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const char* c - the new P4PASSWD setting Error* e - an Error object
|
Returns
|
void
|
Notes
To make the new P4PASSWD setting apply to the next command executed with Run(), DefinePassword() sets the value in the registry and then calls SetPassword().
DefinePassword() does not define a new server-side password for the user.
Call DefinePassword() with either the plaintext password, or its MD5 hash
Example
The following code illustrates how this method might be used to make a Windows client application start up with a default P4PASSWD setting.
|
client.Init( &e ); client.DefinePassword("default_pass", &e);
|
ClientApi::DefinePort( const char *, Error * )
Sets P4PORT in the Windows registry and applies the setting immediately.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const char* c - the new P4PORT setting Error* e - an Error object
|
Returns
|
void
|
Notes
In order to make the new P4PORT setting apply to the next client connection opened with Init(), DefinePort() sets the value in the registry and then calls SetPort().
Example
The following code illustrates how this method might be used to make a Windows client application automatically set itself to access a backup server if the primary server fails to respond. (This example assumes the existence of a backup server that perfectly mirrors the primary server.)
|
client.Init( &e );
if (e.IsFatal()) { e.Clear(); ui.OutputError("No response from server - switching to backup!\n"); client.DefinePort("backup:1666", &e); client.Init( &e ); }
|
The first command to which the primary server fails to respond results in the error message and the program reinitializing the client to point to the server at backup:1666. Subsequent commands do not display the warning because the new P4PORT value has been set in the registry.
ClientApi::DefineUser( const char *, Error * )
Sets P4USER in the Windows registry and applies the setting immediately.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const char* c - the new P4USER setting Error* e - an Error object
|
Returns
|
void
|
Notes
To make the new P4USER setting apply to the next command executed with Run(), DefineUser() sets the value in the registry and then calls SetUser().
Example
The following code illustrates how this method might be used to make a Windows client application start up with a default P4USER setting.
|
client.Init( &e ); client.DefineUser("default_user", &e);
|
ClientApi::Dropped( )
Check if connection is no longer usable.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
None
|
Returns
|
int - nonzero if the connection has dropped
|
Notes
Dropped() is usually called after Run(); it then checks whether the command completed successfully. If the Init() is only followed by one Run(), as in samplemain.cc, calling Final() and then checking the Error is sufficient to see whether the connection was dropped. However, if you plan to make many calls to Run() after one call to Init(), Dropped() provides a way to check that the commands are completing without actually cleaning up the connection with Final().
Example
The Dropped() method is useful if you want to reuse a client connection multiple times, and need to make sure that the connection is still alive.
For example, an application for stress-testing a Perforce server might run "p4 have" 10,000 times or until the connection dies:
|
ClientApi client; MyClientUser ui; //this ClientUser subclass doesn't output anything. Error e;
client.Init( &e ); int count = 0; while ( !( client.Dropped() ) && count < 10000 ) { count++; client.Run("have", &ui); } printf ("Checked have list %d times.\n", count); client.Final( &e ); // Clean up connection.
|
If the Dropped() result is true, the while loop ends. The actual error message remains inaccessible until after the call to client.Final() to close the connection and store the error.
ClientApi::Final( Error * )
Close connection and return error count.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
Error* e - an Error object
|
Returns
|
int - final number of errors
|
Notes
Call this method after you are finished using the ClientApi object in order to clean up the connection. Every call to Init() must eventually be followed by exactly one call to Final().
Example
The following example is a slight modification of samplemain.cc, and reports the number of errors before the program exits:
|
client.Init( &e );
client.SetArgv( argc - 2, argv + 2 ); client.Run( argv[1], &ui );
printf ("There were %d errors.\n", client.Final( &e ));
|
ClientApi::GetClient( )
Get current client setting.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
None
|
Returns
|
const StrPtr& - a reference to the client setting
|
Notes
The return value of GetClient() is a fixed reference to this ClientApi object's setting.
Assigning the return value to a StrPtr results in a StrPtr containing a Text() value that changes if the ClientApi object's client setting changes.
Assigning the return value to a StrBuf copies the text in its entirety for future access, rather than simply storing a reference to data that might change later.
Under some circumstances, GetClient() calls GetHost() and returns that value - specifically, if no suitable P4CLIENT value is available in the environment, or previously set with SetClient(). (This is why, under the Perforce client, client name defaults to the host name if not explicitly set.)
In some instances, GetHost() does not return valid results until after a call to Init() - see the GetHost() documentation for details.
Example
This example demonstrates the use of GetClient() and the difference between StrPtrs and StrBufs.
|
ClientApi client; StrPtr p; StrBuf b;
client.Init(); client.SetClient("one"); p = client.GetClient(); b = client.GetClient(); client.SetClient("two");
printf("Current client %s = %s\n", client.GetClient().Text(), p.Text()); printf("Previous client setting was %s\n", b.Text());
|
Executing the preceding code produces the following output:
|
Current client two = two Previous client setting was one
|
ClientApi::GetCwd( )
Get current working directory.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
None
|
Returns
|
const StrPtr& - a reference to the name of the current directory
|
Notes
See GetClient() for more about the StrPtr return value.
If the working directory has been set by a call to SetCwd(), subsequent calls to GetCwd() return that setting regardless of the actual working directory.
Example
The following example demonstrates the usage of GetCwd().
|
ClientApi client;
printf("Current directory is %s\n", client.GetCwd().Text());
|
Executing the preceding code produces the following output:
|
C:\perforce> a.out Current directory is c:\perforce
|
ClientApi::GetConfig( )
Get current configuration file.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
None
|
Returns
|
const StrPtr& - a reference to the config file setting
|
Notes
See GetClient() for more about the StrPtr return value.
If the P4CONFIG has not been set, GetConfig() returns "noconfig".
Example
The following example demonstrates the usage of GetConfig().
|
ClientApi client;
printf("Current P4CONFIG is %s\n", client.GetConfig().Text());
|
Executing the preceding code without having specified a configuration file produces the following output:
|
C:\perforce> a.out Current directory is noconfig
|
ClientApi::GetHost( )
Get client hostname.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
None
|
Returns
|
const StrPtr& - a reference to the hostname
|
Notes
See GetClient() for more about the StrPtr return value.
In some instances, GetHost() is not valid until after the network connection has been established with Init(). GetHost() attempts to pull its value from earlier SetHost() calls, then from P4HOST in the environment, and then from the value of "hostname" returned by the client OS. If none of these is applicable, a reverse DNS lookup is performed, but the lookup will not work unless the connection has been established with Init().
To guarantee valid results, call GetHost() only after Init() or SetHost(). As GetHost() may sometimes be called during the execution of GetClient(), this warning applies to both methods.
As noted above, GetHost() does not necessarily return the actual hostname of the machine if it has been overridden by P4HOST or an earlier call to SetHost().
Example
The following example demonstrates the usage of GetHost().
|
ClientApi client; client.Init();
printf("Client hostname is %s\n", client.GetHost().Text());
|
Executing the preceding code produces the following output:
|
shire% a.out Client hostname is shire
|
ClientApi::GetOs( )
Get name of client operating system.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
None
|
Returns
|
const StrPtr& - a reference to the OS string
|
Notes
See GetClient() for more about the StrPtr return value.
GetOs() returns one of "UNIX", "vms", "NT", "Mac", or null.
Example
The following example demonstrates the usage of GetOs().
|
ClientApi client;
printf ("Client OS is %s\n", client.GetOs().Text());
|
Executing the preceding code under Windows produces the following output:
|
C:\perforce> a.out Client OS is NT
|
Executing the preceding code on a UNIX machine produces the following output:
|
shire$ a.out Client OS is UNIX
|
ClientApi::GetPassword( )
Get password setting.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
None
|
Returns
|
const StrPtr& - a reference to the password
|
Notes
See GetClient() for more about the StrPtr return value.
This method returns the password currently set on the client, which may or may not be the one set on the server for this user. The command "p4 passwd" sets P4PASSWD on the client machine to an MD5 hash of the actual password, in which case GetPassword() returns this MD5 hash rather than the plaintext version.
However, if the user sets P4PASSWD directly with the plaintext version, GetPassword() returns that plaintext version. In both instances, the result is the same as that displayed by "p4 set" or an equivalent command that displays the value of the P4PASSWD environment variable.
SetPassword() overrides the P4PASSWD value, and subsequent GetPassword() calls return the new value set by SetPassword() rather than the one in the environment.
Example
The following example demonstrates the usage of GetPassword().
|
ClientApi client;
printf ("Your password is %s\n", client.GetPassword().Text());
|
The following session illustrates the effect of password settings on GetPassword():
|
> p4 set P4PASSWD=p455w04d > a.out Your password is p455w04d
> p4 passwd Enter new password: Re-enter new password: Password updated.
> a.out Your password is 6F577E10961C8F7B519501097131787C
|
ClientApi::GetPort( )
Get current port setting.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
None
|
Returns
|
const StrPtr& - a reference to the port setting
|
Notes
See GetClient() for more about the StrPtr return value.
If the environment variable P4PORT is unset, GetPort() sets the port to the default value of perforce:1666.
Example
The following example demonstrates the usage of GetPort().
|
ClientApi client;
printf ("You're looking for a server at %s\n", \ client.GetPort().Text());
|
Executing the preceding code produces the following output:
|
You're looking for a server at perforce:1666
|
ClientApi::GetProtocol( const char * )
Get protocol information for this connection.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const char* v - the name of the protocol variable being checked
|
Returns
|
StrPtr* - a pointer to the variable's value
|
Notes
If the variable is unset, the return value is null. If there is a value, it will be a number in most cases, but in the form of a StrPtr rather than an int.
Call GetProtocol() only after a call to Run(), because protocol information is not available until after a call to Run(). Calling GetProtocol() before Run() results in a return value of null, which looks misleadingly like an indication that the variable is unset.
GetProtocol() reports only on variables set by the server, not variables set by the client with calls to SetProtocol().
Example
The following example code checks whether the server is case-sensitive.
|
... client.Init( &e ); ... client.Run();
if (client.Dropped()) { client.Final( &e ); }
if (client.GetProtocol("nocase")) printf ("Server case-insensitive.\n"); else printf("Server is case-sensitive.\n");
|
ClientApi::GetUser( )
Get current user setting.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
None
|
Returns
|
const StrPtr& - a reference to the user setting
|
Notes
See GetClient() for more about the StrPtr return value.
Example
The following example demonstrates the usage of GetUser().
|
ClientApi client;
printf ("Your username is %s\n", client.GetUser().Text());
|
Executing the preceding code as testuser produces the following output:
|
Your username is testuser
|
ClientApi::Init( Error * )
Establish a connection and prepare to run commands.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
Error* e - an Error object
|
Returns
|
void
|
Notes
Init() must be called to establish a connection before any commands can be sent to the server. Each call to Init() must be followed by exactly one call to Final().
If an error occurs during Init(), it is most likely a connection error, with a severity of E_FATAL.
Example
The following code from samplemain.cc opens a connection with Init(), sets arguments, runs a command, and closes the connection with Final().
|
ClientUser ui; ClientApi client; Error e;
client.Init( &e );
client.SetArgv( argc - 2, argv + 2 ); client.Run( argv[1], &ui );
client.Final( &e );
return 0;
|
ClientApi::Run( const char * )
Run a Perforce command and return when it completes.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const char* func - the name of the command to run
|
Returns
|
void
|
Notes
The func argument to Run() is the Perforce command to run, (for instance, info or files). Command arguments are not included and must be set separately with StrDict::SetArgv().
Initialize the connection with Init() before calling Run(), because without a connection, no commands can be sent to the server. Attempting to call Run() before Init() will probably result in a fatal runtime error.
Run() returns only after the command completes. Note that all necessary calls to ClientUser methods are made during the execution of Run(), as dictated by the server.
Example
The code below runs p4 info, using ClientUser::OutputInfo() to display the results to the user. If a subclass of ClientUser is used here as the ui argument, that subclass's implementation of OutputInfo() is used to display the results of the command.
|
ClientApi client; ClientUser ui; Error e;
client.Init( &e ); client.Run( "info", &ui ); client.Final( &e );
|
ClientApi::SetBreak( KeepAlive *breakCallback )
Establish a callback that is called every 0.5 seconds during command execution.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
KeepAlive *breakCallback - keepalive callback for user interrupt
|
Returns
|
void
|
Notes
To establish the callback routine, you must call SetBreak() after ClientApi::Init().
See Also
KeepAlive::IsAlive()
Example
The following example implements a custom IsAlive() that can be called three times before returning 0 and terminating the connection. If the call to run the changes command takes less than 1.5 seconds to complete on the server side, the program outputs the list of changes. If the call to run the changes command takes more than 1.5 seconds, the connection is interrupted.
|
#include <clientapi.h>
// subclass KeepAlive to implement a customized IsAlive function. class MyKeepAlive : public KeepAlive { public: int IsAlive(); } ;
// Set up the interrupt callback. After being called 3 times, // interrupt 3 times, interrupt the current server operation. int MyKeepAlive::IsAlive() { static int counter = 0; if( ++counter > 3 ) { counter = 0; return( 0 ); } return( 1 ); }
// Now test the callback ClientUser ui; ClientApi client; MyKeepAlive cb; Error e;
client.Init( &e ); client.SetBreak( &cb ); // SetBreak must happen after the Init client.Run( "changes", &ui ); client.Final( &e );
|
ClientApi::SetClient( const StrPtr * )
Sets the client setting to be used for this connection.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const StrPtr* c - the new client setting
|
Returns
|
void
|
Notes
SetClient() does not permanently set the P4CLIENT value in the environment or registry. The new setting applies only to commands executed by calling this ClientApi object's Run() method.
Example
The following example displays two client specifications by calling SetClient() between Run() commands.
|
ClientApi client; ClientUser ui; StrBuf sb1; StrBuf sb2;
sb1 = "client_one"; sb2 = "client_two"; args[0] = "-o";
client.SetClient( &sb1 ); client.SetArgv(1, args); client.Run("client", &ui);
client.SetClient( &sb2 ); client.SetArgv(1, args); client.Run("client", &ui);
|
ClientApi::SetClient( const char * )
Sets the client setting to be used for this connection.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const char* c - the new client setting
|
Returns
|
void
|
Notes
SetClient() does not permanently set the P4CLIENT value in the environment or registry. The new setting applies only to commands executed by calling this ClientApi object's Run() method.
Example
The following example displays two client specifications by calling SetClient() between Run() commands.
|
ClientApi client; ClientUser ui;
char* args[1]; args[0] = "-o";
client.SetClient("client_one"); client.SetArgv(1, args); client.Run("client", &ui);
client.SetClient("client_two"); client.SetArgv(1, args); client.Run("client", &ui);
|
ClientApi::SetCwd( const StrPtr * )
Sets the working directory to be used for this connection.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const StrPtr* c - the new directory path
|
Returns
|
void
|
Notes
SetCwd() does not permanently set a new working directory in the client environment. The new setting applies only to commands executed by calling this ClientApi object's Run() method.
Example
The following code sets different working directories and displays them with p4 info.
|
ClientApi client; ClientUser ui; StrBuf sb1; StrBuf sb2;
sb1 = "C:\one"; sb2 = "C:\two";
client.SetCwd( &sb1 ); client.Run("info", &ui);
client.SetCwd( &sb2 ); client.Run("info", &ui);
|
ClientApi::SetCwd( const char * )
Sets the working directory to be used for this connection.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const char* c - the new directory path
|
Returns
|
void
|
Notes
SetCwd() does not permanently set a new working directory in the client environment. The new setting applies only to commands executed by calling this ClientApi object's Run() method.
Example
The following code sets different working directories and displays them with p4 info.
|
ClientApi client; ClientUser ui;
client.SetCwd("C:\one"); client.Run("info", &ui);
client.SetCwd("C:\two"); client.Run("info", &ui);
|
ClientApi::SetHost( const StrPtr * )
Sets the hostname to be used for this connection.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const StrPtr* c - the new hostname value
|
Returns
|
void
|
Notes
SetHost() does not permanently change the host name of the client or set P4HOST in the environment. The new setting applies only to commands executed by calling this ClientApi object's Run() method.
Example
The following example sets different hostnames and displays them with p4 info.
|
ClientApi client; ClientUser ui; StrBuf sb1; StrBuf sb2;
sb1 = "magic"; sb2 = "shire";
client.SetHost( &sb1 ); client.Run("info", &ui);
client.SetHost( &sb2 ); client.Run("info", &ui);
|
ClientApi::SetHost( const char * )
Sets the hostname to be used for this connection.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const char* c - the new hostname value
|
Returns
|
void
|
Notes
SetHost() does not permanently change the host name of the client or set P4HOST in the environment. The new setting applies only to commands executed by calling this ClientApi object's Run() method.
Example
The following example sets different hostnames and displays them with p4 info.
|
ClientApi client; ClientUser ui;
client.SetHost("magic"); client.Run("info", &ui);
client.SetHost("shire"); client.Run("info", &ui);
|
ClientApi::SetPassword( const StrPtr * )
Sets the password to be used for this connection.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const StrPtr* c - the new password value
|
Returns
|
void
|
Notes
SetPassword() does not permanently change the P4PASSWD value in the environment, nor does it in any way change the password that has been set on the server. The new setting applies only to authentication attempts for commands executed by calling this ClientApi object's Run() method.
Example
The following example demonstrates how to hard-code a password into a client program without making it user-visible.
|
ClientApi client; ClientUser ui; StrBuf sb;
sb = "p455w04d";
client.SetPassword( &sb ); client.SetArgv( argc - 2, argv + 2 ); client.Run(argv[1], &ui);
|
ClientApi::SetPassword( const char * )
Sets the password to be used for this connection.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const char* c - the new password value
|
Returns
|
void
|
Notes
SetPassword() does not permanently change the P4PASSWD value in the environment, nor does it in any way change the password that has been set on the server. The new setting applies only to authentication attempts for commands executed by calling this ClientApi object's Run() method.
Example
The following example demonstrates how to hard-code a password into a client program without making it user-visible.
|
ClientApi client; ClientUser ui;
client.SetPassword("p455w04d"); client.SetArgv( argc - 2, argv + 2 ); client.Run(argv[1], &ui);
|
ClientApi::SetPort( const StrPtr * )
Sets the port to be used to open this connection.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const StrPtr* c - the new port value
|
Returns
|
void
|
Notes
SetPort() does not permanently change the P4PORT value in the environment. The new setting applies only to new connections established by calling this ClientApi object's Init() method.
Example
The following example demonstrates setting a new port value before initializing the connection.
|
ClientApi client; Error e; StrBuf sb;
sb = "magic:1666";
client.SetPort( &sb ); client.Init( &e );
|
ClientApi::SetPort( const char * )
Sets the port to be used to open this connection.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const char* c - the new port value
|
Returns
|
void
|
Notes
SetPort() does not permanently change the P4PORT value in the environment. The new setting applies only to new connections established by calling this ClientApi object's Init() method.
Example
The following example demonstrates setting a new port value before initializing the connection.
|
ClientApi client; Error e;
client.SetPort("magic:1666"); client.Init( &e );
|
ClientApi::SetProg( const StrPtr * )
Sets the application or script name for this connection.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const StrPtr* c - the new program name
|
Returns
|
void
|
Notes
SetProg() sets the identity of a client application as reported by the p4 monitor command, or as recorded by server logging.
Call SetProg() after calling Init() and before calling Run().
See Also
ClientApi::SetVersion()
Example
The following example appears as MyApp in the output of p4 monitor show.
|
ClientApi client; ClientUser ui; StrBuf sb; Error e;
sb.Set( "MyApp" );
client.Init( &e ); client.SetProg( &sb ); client.Run( "info", &ui );
|
ClientApi::SetProg( const char * )
Sets the application or script name for this connection.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const char* c - the new program name
|
Returns
|
void
|
Notes
SetProg() sets the identity of a client application as reported by the p4 monitor command, or as recorded by server logging.
Call SetProg() after calling Init() and before calling Run().
See Also
ClientApi::SetVersion()
Example
The following example appears as MyApp in the output of p4 monitor show.
|
ClientApi client; ClientUser ui; Error e;
client.Init( &e ); client.SetProg( "MyApp" ); client.Run( "info", &ui );
|
ClientApi::SetProtocol( char *, char * )
Sets special protocols for the server to use.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
char* p - the name of the variable to set char* v - the new value for that variable
|
Returns
|
void
|
Notes
SetProtocol() must be called before the connection is established with Init().
The following variables are supported by SetProtocol():
Variable
|
Meaning
|
|---|
|
tag
|
To enable tagged output (if tagged output for the command is supported by the server), set the tag variable to any value.
|
|
specstring
|
To enable specially formatted application forms, set the specstring to any value.
|
|
api
|
Set the api variable to the value corresponding to the level of server behavior your application supports.
|
To protect your code against changes in server level, use the api variable.
For instance, the "p4 info" command supports tagged output as of server release 2003.2, and changes to this format were made in 2004.2. Code requesting tagged output from "p4 info" that was compiled against the 2003.1 API library may break (that is, start producing tagged output) when running against a 2003.2 or newer server. To prevent this from happening, set api to the value corresponding to the desired server release.
Command
|
Set api to
|
Tagged output supported?
|
|---|
|
info
| |
- Only if both server and API are at 2004.2 or greater
- Output is not tagged; behaves like 2003.1 or earlier, even if server supports tagged output.
- Output is tagged; behaves like 2003.2.
- Output is tagged; behaves like 2004.1, 2004.2, or 2005.1.
- Output is tagged; behaves like 2005.2 or greater
|
Example
The following example demonstrates the use of SetProtocol() to enable tagged output. The result of this call is that the ClientUser object uses OutputStat() to handle the output, rather than OutputInfo().
|
ClientApi client; Error e;
client.SetProtocol("tag", ""); client.Init( &e ); client.Run("branches", &ui); client.Final( &e );
|
The following code illustrates how to ensure forward compatibility when compiling against newer versions of the Perforce API or connecting to newer Perforce servers.
|
ClientApi client; Error e;
printf("Output is tagged depending on API or server level.\n"); client.SetProtocol("tag", ""); // request tagged output client.Init( &e ); client.Run("info", &ui); client.Final( &e );
printf("Force 2003.1 behavior regardless of API or server level.\n"); client.SetProtocol("tag", ""); //request tagged output client.SetProtocol("api", "55"); // but force 2003.1 mode (untagged) client.Init( &e ); client.Run("info", &ui); client.Final( &e );
printf("Request 2003.2 output if API and server support it.\n"); client.SetProtocol("tag", ""); // request tagged output client.SetProtocol("api", "56"); // force 2003.2 mode (tagged) client.Init( &e ); client.Run("info", &ui); client.Final( &e );
|
The "p4 info" command supports tagged output only as of server release 2003.2. In the example, the first Run() leaves api unset; if both the client API and Perforce server support tagged output for p4 info (that is, if you link this code with the 2003.2 or later API and run it against a 2003.2 or later server), the output is tagged. If you link the same code with the libraries from the 2003.1 release of the API, however, the first Run() returns untagged output even if connected to a 2003.2 server. By setting api to 55, the second Run() ensures 2003.1 behavior regardless of API or server level. The third call to Run() supports 2003.2 behavior against a 2003.2 server and protects against future changes.
ClientApi::SetProtocolV( char * )
Sets special protocols for the server to use.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
char* nv - the name and value of the variable to set in var=val form
|
Returns
|
void
|
Notes
SetProtocolV() functions identically to SetProtocol(), except that its argument is a single string of the format variable=value.
Example
The following example demonstrates the use of SetProtocolV() to enable tagged output. The result is that the ClientUser object uses OutputStat() to handle the output, rather than OutputInfo().
|
ClientApi client; Error e;
client.SetProtocolV("tag="); client.Init( &e ); client.Run("branches", &ui); client.Final( &e );
|
ClientApi::SetTicketFile( const StrPtr * )
Sets the full path name of the ticket file to be used for this connection.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const StrPtr* c - the full path name of the new ticket file
|
Returns
|
void
|
Notes
SetTicketFile() does not permanently set the P4TICKETS value in the environment or registry. The new setting applies only to commands executed by calling this ClientApi object's Run() method.
Example
The following example sets a ticket file location by calling SetTicketFile().
|
ClientApi client; StrBuf sb;
sb = "/tmp/ticketfile.txt"; client.SetTicketFile( &sb );
|
ClientApi::SetTicketFile( const char * )
Sets the full path name of the ticket file to be used for this connection.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const char* c - the full path name of the new ticket file
|
Returns
|
void
|
Notes
SetTicketFile() does not permanently set the P4TICKETS value in the environment or registry. The new setting applies only to commands executed by calling this ClientApi object's Run() method.
Example
The following example sets a ticket file location by calling SetTicketFile().
|
ClientApi client;
client.SetTicketFile("/tmp/ticketfile.txt");
|
ClientApi::SetUser( const StrPtr * )
Sets the user for this connection.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const StrPtr* c - the new user name setting
|
Returns
|
void
|
Notes
SetUser() does not permanently set the P4USER value in the environment or registry. Calling this method is equivalent to using the "-u" global option from the command line to set the user value for a single command, with the exception that a single ClientApi object can be used to invoke multiple commands in a row.
If the user setting is to be in effect for the command when it is executed, you must call SetUser() before calling Run().
Example
The following example displays two user specifications by calling SetUser() between Run() commands.
|
ClientApi client; Error e; StrBuf sb1; StrBuf sb2;
sb1 = "user1"; sb2 = "user2";
char* args[1]; args[0] = "-o";
client.SetUser( &sb1 ); client.SetArgv(1, args); client.Run("user", &ui);
client.SetUser( &sb2 ); client.SetArgv(1, args); client.Run("user", &ui);
|
ClientApi::SetUser( const char * )
Sets the user for this connection.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const char* c - the new user name setting
|
Returns
|
void
|
Notes
SetUser() does not permanently set the P4USER value in the environment or registry. Calling this method is equivalent to using the "-u" global option from the command line to set the user value for a single command, with the exception that a single ClientApi object can be used to invoke multiple commands in a row.
If the user setting is to be in effect for the command when it is executed, you must call SetUser() before calling Run().
Example
The following example displays two user specifications by calling SetUser() between Run() commands.
|
ClientApi client; Error e;
char* args[1]; args[0] = "-o";
client.SetUser("user1"); client.SetArgv(1, args); client.Run("user", &ui);
client.SetUser("user2"); client.SetArgv(1, args); client.Run("user", &ui);
|
ClientApi::SetVersion( const StrPtr * )
Sets the application or script version for this connection.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const StrPtr* c - the new version number
|
Returns
|
void
|
Notes
SetVersion() sets the version number of a client application as reported by the p4 monitor -e command, or as recorded by server logging.
If a client application compiled with version 2005.2 or later of the API does not call SetVersion(), then the version string reported by p4 monitor -e (and recorded in the server log) defaults to the api value appropriate for the server level as per SetProtocol().
Call SetVersion() after calling Init() and before calling Run().
See Also
ClientApi::SetProtocol()
ClientApi::SetProg()
Example
The following example appears as 2005.2 in the output of p4 monitor show -e.
|
ClientApi client; ClientUser ui; StrBuf sb; Error e;
sb.Set( "2005.2" );
client.Init( &e ); client.SetVersion( &sb ); client.Run( "info", &ui );
|
ClientApi::SetVersion( const char * )
Sets the application or script version for this connection.
Virtual?
|
No
|
Class
|
ClientApi
|
Arguments
|
const char* c - the new version number
|
Returns
|
void
|
Notes
SetVersion() sets the version number of a client application as reported by the p4 monitor -e command, or as recorded by server logging.
If a client application compiled with version 2005.2 or later of the API does not call SetVersion(), then the version string reported by p4 monitor -e (and recorded in the server log) defaults to the api value appropriate for the server level as per SetProtocol().
Call SetVersion() after calling Init() and before calling Run().
See Also
ClientApi::SetProtocol()
ClientApi::SetProg()
Example
The following example appears as 2005.2 in the output of p4 monitor show -e.
|
ClientApi client; ClientUser ui; Error e;
client.Init( &e ); client.SetVersion( "2005.2" ); client.Run( "info", &ui );
|
ClientUser methods
ClientUser::Diff( FileSys *, FileSys *, int, char *, Error * )
Diff two files, and display the results.
Virtual?
|
Yes
|
Class
|
ClientUser
|
Arguments
|
FileSys* f1 - the first file to be diffed FileSys* f2 - the second file to be diffed int doPage - should output be paged? char* diffFlags - flags to diff routine Error* e - an Error object
|
Returns
|
void
|
Notes
This method is used by p4 diff and to display diffs from an interactive p4 resolve. If no external diff program is specified, the diff is carried out with a Diff object (part of the Perforce client API); otherwise, Diff() simply calls the specified external program.
As with Merge(), the external program is invoked with ClientUser::RunCmd().
If doPage is nonzero and the P4PAGER environment variable is set, the output is piped through the executable specified by P4PAGER.
See Also
ClientUser::RunCmd()
Example
In its default implementation, this method is called by a client program when p4 diff is run. For example:
results in a call to Diff() with the arguments:
Argument
|
Value
|
|---|
|
f1
|
a temp file containing the head revision of depot file file.c
|
|
f2
|
the local workspace version of file file.c
|
|
doPage
|
0
|
|
diffFlag
|
c
|
|
e
|
a normal Error object
|
The diff is performed by creating a Diff object, giving it f1 and f2 as its inputs, and -c as its flag. The end result is sent to stdout. If either of the files is binary, the message "files differ" is printed instead.
Selecting the "d" option during an interactive p4 resolve also calls the Diff() method, with the doPage argument set to 1.
If the environment variable P4PAGER or PAGER is set, then setting doPage to 1 causes the diff output to be fed through the specified pager. If P4PAGER and PAGER are unset, dopage has no effect and the resolve routine displays the diff output normally.
To enable a client program to override the default diff routine, create a subclass of ClientUser that overrides the Diff() method, and use this subclass in place of ClientUser.
As an example, suppose that you have a special diff program designed for handling binary files, and you want p4 diff to use it whenever asked to diff binary files (rather than display the default "files differ...").
Furthermore, you want to keep your current P4DIFF setting for the purpose of diffing text files, so you decide to use a new environment variable called P4DIFFBIN to reference the binary diff program. If P4DIFFBIN is set and one of the files is non-text, the P4DIFFBIN program is invoked as P4DIFF is in the default implementation. Otherwise, the default implementation is called.
Most of the following code is copied and pasted from the default implementation.
|
MyClientUser::Diff(FileSys *f1,FileSys *f2,int doPage,char *df,Error *e) { const char *diff = enviro->Get("P4DIFFBIN"); if( diff && (!f1->IsTextual() || !f2->IsTextual()) ) // binary diff { if( !df || !*df ) { RunCmd( diff, 0, f1->Name(), f2->Name(), 0, pager, e ); } else { StrBuf flags; flags.Set( "-", 1 ); flags << df; RunCmd(diff,flags.Text(), f1->Name(), f2->Name(), 0, pager,e); } } else ClientUser::Diff( f1, f2, doPage, df, e ); }
|
ClientUser::Edit( FileSys *, Error * )
Bring up the given file in a text editor. Called by all p4 commands that edit specifications.
Virtual?
|
Yes
|
Class
|
ClientUser
|
Arguments
|
FileSys* f1 - the file to be edited Error* e - an Error object
|
Returns
|
void
|
Notes
The FileSys* argument to Edit() refers to a client temp file that contains the specification that is to be given to the server. Edit() does not send the file to the server; its only job is to modify the file. In the default implementation, Edit() does not return until the editor has returned.
There is also a three-argument version of Edit(), for which the default two-argument version is simply a wrapper. The three-argument version takes an Enviro object as an additional argument, and the two-argument version simply passes the member variable enviro as this argument. Only the two-argument version is virtual.
Example
The p4 client command is one of several Perforce commands that use ClientUser::Edit() to allow the user to modify a specification. When the command is executed, the server sends the client specification to the client machine, where it is held in a temp file. Edit() is then called with that file as an argument, and an editor is spawned. When the editor closes, Edit() returns, and the temp file is sent to the server.
To allow modification of a specification by other means, such as a customized dialog or an automated process, create a subclass of ClientUser that overrides the Edit() method and use this subclass in place of ClientUser.
Suppose that you have already written a function that takes a FileSys as input, opens a custom dialog, and returns when the file has been modified. Replace the body of Edit() in your subclass with a call to your function, as follows:
|
void MyClientUser::Edit( FileSys *f1, Error *e ) { MyDialog(f1); }
|
ClientUser::ErrorPause( char *, Error * )
Outputs an error and prompts for a keystroke to continue.
Virtual?
|
Yes
|
Class
|
ClientUser
|
Arguments
|
char* errBuf - the error message to be printed Error* e - an Error object
|
Returns
|
void
|
Notes
The default implementation of ErrorPause() consists solely of calls to OutputError() and Prompt().
Example
One situation that results in a call to ErrorPause() is an incorrectly edited specification; for example:
|
> p4 client ... Error in client specification. Error detected at line 31. Wrong number of words for field 'Root'. Hit return to continue...
|
In this instance, the first three lines of output were the errBuf argument to ErrorPause(); they were displayed using OutputError().
To display an error and prompt for confirmation within a GUI application, create a subclass of ClientUser that overrides ErrorPause() and use this subclass in place of ClientUser.
Suppose that you have a function MyWarning() that takes a char* as an argument, and displays the argument text in an appropriate popup dialog that has to be clicked to be dismissed. You can implement ErrorPause() as a call to this function, as follows:
|
void MyClientUser::ErrorPause( char *errBuf, Error *e ) { MyWarning(errBuf); }
|
Within a GUI, the warning text and "OK" button are probably bundled into a single dialog, so overriding ErrorPause() is a better approach than overriding OutputError() and Prompt() separately.
ClientUser::File( FileSysType )
Create a FileSys object for reading and writing files in the client workspace.
Virtual?
|
Yes
|
Class
|
ClientUser
|
Arguments
|
FileSysType type - the file type of the file to be created
|
Returns
|
FileSys* - a pointer to the new FileSys.
|
Notes
This method is a wrapper for FileSys::Create().
Example
ClientUser::File() is generally called whenever it's necessary to manipulate files in the client workspace. For example, a p4 sync, p4 edit, or p4 revert makes one call to File() for each workspace file with which the command interacts.
An alternate implementation might return a subclass of FileSys. For example, if you have defined a class MyFileSys and want your MyClientUser class to use members of this class rather than the base FileSys, reimplement File() to return a MyFileSys instead:
|
FileSys * MyClientUser::File( FileSysType type ) { return MyFileSys::Create( type ); }
|
ClientUser::Finished( )
Called after client commands finish.
Virtual?
|
Yes
|
Class
|
ClientUser
|
Arguments
|
None
|
Returns
|
void
|
Notes
This function is called by the server at the end of every Perforce command, but in its default implementation, it has no effect. The default implementation of this function is empty - it takes nothing, does nothing, and returns nothing.