specdata.cc #1

  • //
  • guest/
  • perforce_software/
  • p4/
  • 2017-1/
  • support/
  • specdata.cc
  • View
  • Commits
  • Open Download .zip Download (5 KB)
/*
 * Copyright 1995, 2000 Perforce Software.  All rights reserved.
 *
 * This file is part of Perforce - the FAST SCM System.
 */

/*
 * specdata.cc -- SpecWords, SpecData, SpecDataTable
 */

# include <stdhdrs.h>
# include <charman.h>
# include <debug.h>

# include <strbuf.h>
# include <strdict.h>
# include <strtable.h>

# include <error.h>
# include <errorlog.h>

# include "spec.h"
# include <msgdb.h>

/*
 * SpecWords -- array of words in a spec value, allowing surrounding "'s
 */

int
SpecWords::Split()
{
	int wc = 0;
	char *buf = Text();

	while( wc < SpecWordsMax )
	{
	    // Skip blanks 

	    while( isAspace( buf ) ) buf++;
	    if( !*buf ) break;

	    // First letter of new word 

	    if( *buf == '"' ) 
	    {
		// quoted

		wv[ wc++ ] = ++buf;
		while( *buf && *buf != '"' ) buf++;
	    }
	    else
	    {
		// Non-quoted

		wv[ wc++ ] = buf;
		while( *buf && !isAspace( buf ) ) buf++;
	    }

	    if( !*buf ) break;

	    // First blank after word 

	    *buf++ = '\0';
	}

	wv[ wc ] = 0;
	return wc;
}

void
SpecWords::Join( int wc )
{
	// To handle single line comments, there are no values
	// returned in **words, just **cmts,  check for any null
	// values and return a null string.

	for( int i = 0; i < wc; i++ )
	{
	    if( !wv[i] )
	    {
	        *this << "";
	        return;
	    }
	}

	for( int i = 0; i < wc; i++ )
	{
	    if( i )
		*this << " ";
	    // quote if spaces or null
	    if( !*wv[i] || strchr( wv[i], ' ' ) || strchr( wv[i], '#' ) )
		*this << "\"" << wv[i] << "\"";
	    else
		*this << wv[i];
	}
}

/*
 * SpecData -- default Get()/Set() that do line splitting/joining
 */

StrPtr *
SpecData::GetLine( SpecElem *sd, int x, const char **cmt )
{
	if( !Get( sd, x, tVal.wv, cmt ) )
	    return 0;

	if( sd->IsWords() )
	{
	    tVal.Clear();

	    // join the maximum number of words.
	    if( sd->maxWords && tVal.wv[sd->maxWords-1] ) 
	        tVal.Join( sd->maxWords );
	    else 
	        tVal.Join( sd->nWords );
	}
	else
	{
	    tVal.Set( tVal.wv[0] );
	}

	return &tVal;
}

void
SpecData::SetLine( SpecElem *sd, int x, const StrPtr *val, Error *e )
{
	if( sd->IsWords() )
	{
	    tVal.Set( *val );
	    int wordCount = tVal.Split();
	    int wordMax = sd->maxWords ? sd->maxWords : sd->nWords;

	    if( wordCount < sd->nWords || wordCount > wordMax)
	    {
		e->Set( MsgDb::FieldWords ) << sd->tag;
		return;
	    } 
	}
	else
	{
	    tVal.wv[0] = val->Text();
	}

	Set( sd, x, tVal.wv, e );
}

void
SpecData::SetComment( SpecElem *sd, int x, const StrPtr *val, int nl, Error *e )
{
	tVal.wv[0] = val->Text();
	Comment( sd, x, tVal.wv, nl, e );
}

int
SpecData::Get( SpecElem *sd, int x, const char **wv, const char **cmt )
{
	return Get( sd, x, (char **)wv, (char **)cmt );
}

void	
SpecData::Set( SpecElem *sd, int x, const char **wv, Error *e )
{
	Set( sd, x, (char **)wv, e );
}

void
SpecData::Comment( SpecElem *sd, int x, const char **wv, int nl, Error *e )
{
	Comment( sd, x, (char **)wv, nl, e );
}

int
SpecData::Get( SpecElem *sd, int x, char **wv, char **cmt )
{
	AssertError.Set( E_FATAL, "SpecData::Get called!" );
	AssertLog.Abort( &AssertError );
	return 0;
}

void	
SpecData::Set( SpecElem *sd, int x, char **wv, Error *e )
{
	e->Set( E_FATAL, "SpecData::Set called!" );
}

void
SpecData::Comment( SpecElem *sd, int x, char **wv, int nl, Error *e )
{
	// No message,  comments will be ignored.
}

/*
 * SpecDataTable -- a SpecData interface to a StrDict 
 */

SpecDataTable::SpecDataTable( StrDict *dict )
{
	empty.Clear();
	if( dict )
	{
	    table = dict;
	    privateTable = 0;
	}
	else
	{
	    table = new StrBufDict;
	    privateTable = 1;
	}
}

SpecDataTable::~SpecDataTable()
{
	if( privateTable )
	    delete table;
}

StrPtr *
SpecDataTable::GetLine( SpecElem *sd, int x, const char **cmt )
{
	*cmt = 0;

	StrPtr *l, *c;
	StrBuf cTag = sd->tag;
	cTag << "Comment";

	if( sd->IsList() )
	    l = table->GetVar( sd->tag, x );
	else
	    l = table->GetVar( sd->tag );

	if( !l )
	    return 0;

	if( sd->IsList() )
	    c = table->GetVar( cTag, x );
	else
	    c = table->GetVar( cTag );

	if( c && c->Length() )
	{
	    // We store and send the comments with the hashes, but then append
	    // them during form formatting: got to strip the off now.

	    *cmt = c->Text();
	    while( **cmt == '#' )
	        *cmt = *cmt + 1;
	}

	return l;
}

void
SpecDataTable::SetLine( SpecElem *sd, int x, const StrPtr *val, Error *e )
{
	if( sd->IsList() )
	    table->SetVar( sd->tag, x, *val );
	else
	    table->SetVar( sd->tag, *val );
}

void
SpecDataTable::SetComment( SpecElem *sd, int x, const StrPtr *val, int nl, Error *e )
{
	StrBuf name;
	name << sd->tag << "Comment";

	if( sd->IsList() )
	{
	    table->SetVar( name, x - (nl ? 0 : 1), *val );
	    table->SetVar( sd->tag, x, empty );
	}
	else
	    table->SetVar( name, *val );
}
# Change User Description Committed
#1 22288 mark_mears import 2017.1 code drop