/* $Id$ */ /* * FedStage DRMAA utilities library * Copyright (C) 2006-2008 FedStage Systems * * 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 3 of the License, 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, see . */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #ifndef lint static char rcsid[] # ifdef __GNUC__ __attribute__ ((unused)) # endif = "$Id$"; #endif #define DRMAA_MAX_ATTR_LEN (16 * 1024 - 1) static const char* fsd_template_get_attr( const fsd_template_t *self, const char *name ) { const fsd_attribute_t *attr = NULL; if( name == NULL ) fsd_exc_raise_code( FSD_ERRNO_INVALID_ARGUMENT ); attr = self->by_name( self, name ); if( attr == NULL || attr->is_vector ) fsd_exc_raise_fmt( FSD_ERRNO_INVALID_ARGUMENT, "invalid scalar attribute name: %s", name ); return (const char*) self->attributes[ attr->code ]; } static void fsd_template_set_attr( fsd_template_t *self, const char *name, const char *value ) { const fsd_attribute_t *attr = NULL; fsd_log_enter(("(%s=%s)", name, value)); if( name == NULL ) fsd_exc_raise_code( FSD_ERRNO_INVALID_ARGUMENT ); attr = self->by_name( self, name ); if( attr == NULL || attr->is_vector ) fsd_exc_raise_fmt( FSD_ERRNO_INVALID_ARGUMENT, "invalid scalar attribute name: %s", name ); if( value != NULL ) { if (strlen (value) > DRMAA_MAX_ATTR_LEN) fsd_exc_raise_fmt( FSD_ERRNO_INVALID_ARGUMENT, "Argument length exceeds max size: %d > %d", (int)strlen(value), DRMAA_MAX_ATTR_LEN ); if( self->attributes[ attr->code ] != NULL ) { fsd_free(self->attributes[ attr->code ]); } self->attributes[ attr->code ] = fsd_strdup( value ); } else self->attributes[ attr->code ] = NULL; } static const char* const* fsd_template_get_v_attr( const fsd_template_t *self, const char *name ) { const fsd_attribute_t *attr = NULL; if( name == NULL ) fsd_exc_raise_code( FSD_ERRNO_INVALID_ARGUMENT ); attr = self->by_name( self, name ); if( attr == NULL || ! attr->is_vector ) fsd_exc_raise_fmt( FSD_ERRNO_INVALID_ARGUMENT, "invalid vector attribute name: %s", name ); return (const char* const*) self->attributes[ attr->code ]; } static void fsd_template_set_v_attr( fsd_template_t *self, const char *name, const char **value ) { const fsd_attribute_t *attr = NULL; char **volatile v = NULL; if( name == NULL ) fsd_exc_raise_code( FSD_ERRNO_INVALID_ARGUMENT ); attr = self->by_name( self, name ); if( attr == NULL || ! attr->is_vector ) fsd_exc_raise_fmt( FSD_ERRNO_INVALID_ARGUMENT, "invalid vector attribute name: %s", name ); TRY { int code = attr->code; if( value != NULL ) v = fsd_copy_vector( value ); if( self->attributes[code] != NULL ) fsd_free_vector( self->attributes[code] ); self->attributes[code] = v; v = NULL; } FINALLY { fsd_free_vector( v ); } END_TRY } static void fsd_template_destroy( fsd_template_t *self ) { unsigned i; for( i = 0; i < self->n_attributes; i++ ) if( self->attributes[i] != NULL ) { const fsd_attribute_t *attr; attr = self->by_code( self, i ); if( attr ) { if( attr->is_vector ) fsd_free_vector( self->attributes[i] ); else fsd_free( self->attributes[i] ); } } fsd_free( self->attributes ); fsd_free( self ); } fsd_template_t * fsd_template_new( fsd_template_by_name_method *by_name_method, fsd_template_by_code_method *by_code_method, unsigned n_attributes ) { fsd_template_t *volatile self = NULL; TRY { fsd_malloc( self, fsd_template_t ); self->attributes = NULL; self->n_attributes = 0; self->get_attr = fsd_template_get_attr; self->set_attr = fsd_template_set_attr; self->get_v_attr = fsd_template_get_v_attr; self->set_v_attr = fsd_template_set_v_attr; self->by_name = by_name_method; self->by_code = by_code_method; self->destroy = fsd_template_destroy; fsd_calloc( self->attributes, n_attributes, void* ); self->n_attributes = n_attributes; } EXCEPT_DEFAULT { if( self ) self->destroy( self ); fsd_exc_reraise(); } END_TRY return self; }