00001 #include <citrus/config.h>
00002
00003 #include <stdio.h>
00004 #include <sys/types.h>
00005 #include <sys/stat.h>
00006 #include <unistd.h>
00007
00008 #include <citrus/Unit.H>
00009 #include <citrus/DimensionGroup.H>
00010
00040 int UnitReadConfig( const char* filename ) ;
00041
00044 Unit* Unit::s_allUnits = 0 ;
00045
00049 Unit* Unit::s_dimensionless = 0 ;
00050
00052 Unit::Unit( const char* name, const char* abbr,
00053 double scale, DimensionGroup* dgrp )
00054 {
00055 m_name = new char[strlen(name)+1] ;
00056 strcpy( m_name, name ) ;
00057
00058 m_abbr = new char[strlen(abbr)+1] ;
00059 strcpy( m_abbr, abbr ) ;
00060
00061 m_dgrp = dgrp ;
00062 if (m_dgrp)
00063 m_dgrp->p_add( this ) ;
00064
00065 m_scale = scale ;
00066
00067 m_offsetVal = 0.0 ;
00068 m_offsetPolicy= false ;
00069 m_avoid = false ;
00070 m_prefix = true ;
00071 m_pluralPolicy= CITRUS_PLURAL_NORMAL ;
00072 m_pluralName = 0 ;
00073
00074 if ( s_allUnits)
00075 m_next = s_allUnits ;
00076 else
00077 m_next = 0 ;
00078
00079 s_allUnits = this ;
00080 }
00081
00083 Unit::~Unit()
00084 {
00085 if (m_name)
00086 delete [] m_name ;
00087
00088 if (m_abbr)
00089 delete [] m_abbr ;
00090
00091 if ( m_pluralPolicy= CITRUS_PLURAL_SPECIAL && m_pluralName )
00092 delete [] m_pluralName ;
00093
00094 if (m_dgrp)
00095 m_dgrp->p_remove( this ) ;
00096
00097 if ( s_allUnits == this ) {
00098 s_allUnits = m_next ;
00099 } else {
00100 Unit* tmp = s_allUnits ;
00101 while ( tmp && tmp->m_next != this )
00102 tmp = tmp->m_next ;
00103 tmp->m_next = m_next ;
00104 }
00105 }
00106
00108 void Unit::plural( const char* name )
00109 {
00110 if (m_pluralPolicy == CITRUS_PLURAL_SPECIAL && m_pluralName)
00111 delete [] m_pluralName ;
00112
00113 m_pluralPolicy = CITRUS_PLURAL_SPECIAL ;
00114 m_pluralName = new char[strlen(name)+1] ;
00115 strcpy( m_pluralName, name ) ;
00116 }
00117
00119 void Unit::plural( int type )
00120 {
00121 if (m_pluralPolicy == CITRUS_PLURAL_SPECIAL && m_pluralName)
00122 delete [] m_pluralName ;
00123
00124 m_pluralPolicy = type ;
00125 }
00126
00128 Unit* Unit::dimensionless()
00129 {
00130 return s_dimensionless ;
00131 }
00132
00136 Unit* Unit::find( const char* unit_abbr )
00137 {
00138 Unit* tmp = s_allUnits ;
00139 while ( tmp && strcmp(tmp->abbr(), unit_abbr ) )
00140 tmp = tmp->next() ;
00141 return tmp ;
00142 }
00143
00147 Unit* Unit::findByFullName( const char* unit_name )
00148 {
00149 Unit* tmp = s_allUnits ;
00150 while ( tmp ) {
00151 if ( ! strcmp(tmp->name(), unit_name ) )
00152 return tmp ;
00153 else {
00154 if (tmp->pluralPolicy() == CITRUS_PLURAL_SPECIAL) {
00155 if ( ! strcmp(tmp->pluralForm(), unit_name ) )
00156 return tmp ;
00157 } else if ( tmp->pluralPolicy() == CITRUS_PLURAL_NORMAL) {
00158 int sl = strlen( tmp->name() ) ;
00159 if ( ( strstr(unit_name, tmp->name() ) == unit_name ) &&
00160 (unit_name[sl] == 's') && (unit_name[sl+1] == '\0') ) {
00161 return tmp ;
00162 }
00163 }
00164 }
00165 tmp = tmp->next() ;
00166 }
00167 return 0 ;
00168 }
00169
00170 extern int updebug ;
00181 bool Unit::initialize( const char* config )
00182 {
00183 struct stat s ;
00184 int i = 0 ;
00185 int ok = 0 ;
00186 char* initList[] =
00187 {
00188 CITRUS_CONFIG "/units.xml",
00189 "~/.citrus/units.xml",
00190 0
00191 } ;
00192
00193 if ( s_dimensionless != 0 )
00194 return false ;
00195
00196 if ( !config )
00197 config = initList[i++] ;
00198
00199 do {
00200 if (! stat( config, &s ) ) {
00201 if ( ! UnitReadConfig( config ) )
00202 ok = 1 ;
00203 }
00204 config = initList[i++] ;
00205 } while ( (!ok) && config ) ;
00206
00207 if ( !ok )
00208 return false ;
00209
00210 s_dimensionless = Unit::find("none") ;
00211
00212
00213 return true ;
00214 }
00215
00217 Unit* Unit::first()
00218 {
00219 return s_allUnits ;
00220 }