LAL  7.5.0.1-08ee4f4
UnitDefs.c
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2007 Jolien Creighton, John Whelan
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with with program; see the file COPYING. If not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA
18 */
19 
20 #include <lal/LALStdlib.h>
21 #include <string.h>
22 #include <ctype.h>
23 #include <lal/Units.h>
24 
25 #define UNITDEFSC_TEMPSIZE 20
26 
27 
28 /**
29  * \author J. T. Whelan <john.whelan@ligo.org>
30  * \addtogroup UnitDefs_c
31  *
32  * \brief Defines basic and derived SI units and a function to produce a text
33  * string corresponding to a unit structure.
34  *
35  * XLALUnitAsString() converts the unit structure
36  * <tt>*input</tt> into a text string which is stored in the character
37  * vector <tt>*output</tt>. Note that the resulting text string is
38  * expressed solely in terms of the basic units (m, kg, s, A,
39  * K, strain and counts), and is thus not necessarily the most
40  * convenient way to check the units of a quantity. A better method is
41  * to construct a unit structure containing the expected units, then
42  * compare that to the actual units using XLALUnitCompare().
43  *
44  * XLALParseUnitString() reconstructs the original
45  * \c LALUnit structure from the string output by
46  * XLALUnitAsString(). It is very sensitive to the exact format
47  * of the string and is not intended for use in parsing user-entered
48  * strings.
49  *
50  * ### Algorithm ###
51  *
52  * XLALUnitAsString() moves through the unit structure, appending
53  * the appropriate text to the string as it goes along.
54  *
55  * XLALParseUnitString() moves through the input string, one
56  * character at a time, building an \c LALUnit structure as a it
57  * goes along, so long as it encounters precisely the syntax expected.
58  *
59  * ### Notes ###
60  *
61  * This file also defines a number of \c constant unit structures
62  * (declared \c extern in \ref Units_h). Zeroth is
63  * \c lalDimensionlessUnit, which is simply a \c LALUnit
64  * structure to be associated with a unitless quantity.
65  * First, the relevant fundamental SI units and two custom units of use in
66  * gravitational wave detection:
67  *
68  * <table><tr><th>Constant</th><th>Name</th><th>Abbr.</th><th>Physical Quantity</th></tr>
69  * <tr><td>#lalMeterUnit</td><td>meter</td><td>m</td><td>length</td></tr>
70  * <tr><td>#lalKiloGramUnit</td><td>kilogram</td><td>kg</td><td>mass</td></tr>
71  * <tr><td>#lalSecondUnit</td><td>second</td><td>s</td><td>time</td></tr>
72  * <tr><td>#lalAmpereUnit</td><td>ampere</td><td>A</td><td>electric current</td></tr>
73  * <tr><td>#lalKelvinUnit</td><td>kelvin</td><td>K</td><td>thermodynamic temperature</td></tr>
74  * <tr><td>#lalStrainUnit</td><td>strain</td><td>\f$\epsilon\f$</td><td>gravitational strain</td></tr>
75  * <tr><td>#lalADCCountUnit</td><td>ADC count</td><td>count</td><td>A-to-D converter counts</td></tr>
76  * </table>
77  *
78  * Next, the named derived units in the SI \cite Halliday_2001 :
79  *
80  * <table><tr><th>Constant</th><th>Name</th><th>Abbr.</th><th>Physical Quantity</th><th>Def.</th><th>Fundamental</th></tr>
81  * <tr><td>#lalHertzUnit</td><td>hertz</td><td>Hz</td><td>frequency</td><td> s\f$^{-1}\f$</td><td>s\f$^{-1}\f$</td></tr>
82  * <tr><td>#lalNewtonUnit</td><td>newton</td><td>N</td><td>force</td><td> kg\f$\cdot\f$ m/s\f$^2\f$</td><td>m kg s\f$^{-2}\f$</td></tr>
83  * <tr><td>#lalPascalUnit</td><td>pascal</td><td>Pa</td><td>pressure</td><td> N/m\f$^2\f$</td><td>m\f$^{-1}\f$ kg s\f$^{-2}\f$</td></tr>
84  * <tr><td>#lalJouleUnit</td><td>joule</td><td>J</td><td>energy</td><td> N\f$\cdot\f$m</td><td>m\f$^2\f$ kg s\f$^{-2}\f$</td></tr>
85  * <tr><td>#lalWattUnit</td><td>watt</td><td>W</td><td>power</td><td> J/s</td><td>m\f$^2\f$ kg s\f$^{-3}\f$</td></tr>
86  * <tr><td>#lalCoulombUnit</td><td>coulomb</td><td>C</td><td>electric charge</td><td>A\f$\cdot\f$s</td><td>s A</td></tr>
87  * <tr><td>#lalVoltUnit</td><td>volt</td><td>V</td><td>potential</td><td> W/A</td><td>m\f$^2\f$ kg s\f$^{-3}\f$ A\f$^{-1}\f$</td></tr>
88  * <tr><td>#lalOhmUnit</td><td>ohm</td><td>\f$\Omega\f$</td><td>resistance</td><td> V/A</td><td>m\f$^2\f$ kg s\f$^{-3}\f$ A\f$^{-2}\f$</td></tr>
89  * <tr><td>#lalFaradUnit</td><td>farad</td><td>F</td><td>capacitance</td><td> C/V</td><td>m\f$^{-2}\f$ kg\f$^{-1}\f$ s\f$^4\f$ A\f$^2\f$</td></tr>
90  * <tr><td>#lalWeberUnit</td><td>weber</td><td>Wb</td><td>magnetic flux</td><td> V\f$\cdot\f$s</td><td>m\f$^2\f$ kg s\f$^{-2}\f$ A\f$^{-1}\f$</td></tr>
91  * <tr><td>#lalHenryUnit</td><td>henry</td><td>H</td><td>inductance</td><td> V\f$\cdot\f$s/A</td><td>m\f$^2\f$ kg s\f$^{-2}\f$ A\f$^{-2}\f$</td></tr>
92  * <tr><td>#lalTeslaUnit</td><td>tesla</td><td>T</td><td>magnetic flux density</td><td> Wb/m\f$^2\f$</td><td>kg s\f$^{-2}\f$ A\f$^{-1}\f$</td></tr>
93  * </table>
94  *
95  * The powers of ten (SI prefixes)
96  *
97  * <table><tr><th>Constant</th><th>Prefix</th><th>Abbr.</th><th>Value</th></tr>
98  * <tr><td>#lalYottaUnit</td><td>yotta</td><td>Y</td><td>\f$10^{ 24}\f$</td></tr>
99  * <tr><td>#lalZettaUnit</td><td>zetta</td><td>Z</td><td>\f$10^{ 21}\f$</td></tr>
100  * <tr><td>#lalExaUnit</td><td>exa</td><td>E</td><td>\f$10^{ 18}\f$</td></tr>
101  * <tr><td>#lalPetaUnit</td><td>peta</td><td>P</td><td>\f$10^{ 15}\f$</td></tr>
102  * <tr><td>#lalTeraUnit</td><td>tera</td><td>T</td><td>\f$10^{ 12}\f$</td></tr>
103  * <tr><td>#lalGigaUnit</td><td>giga</td><td>G</td><td>\f$10^{ 9}\f$</td></tr>
104  * <tr><td>#lalMegaUnit</td><td>mega</td><td>M</td><td>\f$10^{ 6}\f$</td></tr>
105  * <tr><td>#lalKiloUnit</td><td>kilo</td><td>k</td><td>\f$10^{ 3}\f$</td></tr>
106  * <tr><td>#lalHectoUnit</td><td>hecto</td><td>h</td><td>\f$10^{ 2}\f$</td></tr>
107  * <tr><td>#lalDekaUnit</td><td>deka</td><td>da</td><td>\f$10^{ 1}\f$</td></tr>
108  * <tr><td>#lalDeciUnit</td><td>deci</td><td>d</td><td>\f$10^{ -1}\f$</td></tr>
109  * <tr><td>#lalCentiUnit</td><td>centi</td><td>c</td><td>\f$10^{ -2}\f$</td></tr>
110  * <tr><td>#lalMilliUnit</td><td>milli</td><td>m</td><td>\f$10^{ -3}\f$</td></tr>
111  * <tr><td>#lalMicroUnit</td><td>micro</td><td>\f$\mu\f$</td><td>\f$10^{ -6}\f$</td></tr>
112  * <tr><td>#lalNanoUnit</td><td>nano</td><td>n</td><td>\f$10^{ -9}\f$</td></tr>
113  * <tr><td>#lalPicoUnit</td><td>pico</td><td>p</td><td>\f$10^{-12}\f$</td></tr>
114  * <tr><td>#lalFemtoUnit</td><td>femto</td><td>f</td><td>\f$10^{-15}\f$</td></tr>
115  * <tr><td>#lalAttoUnit</td><td>atto</td><td>a</td><td>\f$10^{-18}\f$</td></tr>
116  * <tr><td>#lalZeptoUnit</td><td>zepto</td><td>z</td><td>\f$10^{-21}\f$</td></tr>
117  * <tr><td>#lalYoctoUnit</td><td>yocto</td><td>y</td><td>\f$10^{-24}\f$</td></tr>
118  * </table>
119  *
120  * And finally a couple of convenient scaled units:
121  *
122  * <table><tr><th>Constant</th><th>Name</th><th>Abbr.</th><th>Def.</th><th>Fundamental</th></tr>
123  * <tr><td>#lalGramUnit</td><td>gram</td><td>g</td><td> \f$10^{-3}\f$ kg</td><td>\f$10^{-3}\f$ kg</td></tr>
124  * <tr><td>#lalAttoStrainUnit</td><td>attostrain</td><td>a\f$\epsilon\f$</td><td>\f$10^{-18} \epsilon\f$</td><td>\f$10^{-18} \epsilon\f$</td></tr>
125  * <tr><td>#lalPicoFaradUnit</td><td>picofarad</td><td>pF</td><td>\f$10^{-12}\f$ F</td><td>\f$10^{-12}\f$ m\f$^{-2}\f$ kg\f$^{-1}\f$ s\f$^4\f$ A\f$^2\f$</td></tr>
126  * </table>
127  *
128  */
129 /** @{ */
130 
131 /**
132  * To convert a units structure to a string repesentation, we need to
133  * define the names of the basic units.
134  */
136 {
137  "m", "kg", "s", "A", "K", "strain", "count"
138 };
139 
140 /* ********************************************************
141  * *
142  * Predefined units *
143  * *
144  *********************************************************/
145 
146 /* Predefined constant units make it easier for programmers to specify
147  * and compare (using XLALUnitCompare) units more easily. Those given
148  * here are an example; more can be added.
149  */
150 
151 /* LALUnitsTest.c will verify the definitions of the derived units,
152  * for example using XLALUnitRaise, XLALUnitMultiply and XLALUnitCompare
153  * to show that 1 Farad = 1 Coulomb Volt^-1
154  */
155 
156 const LALUnit lalDimensionlessUnit = { 0, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< dimensionless units */
157 
158 /** \name Basic Units */
159 /** @{ */
160 const LALUnit lalMeterUnit = { 0, { 1, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< meter [m] */
161 const LALUnit lalKiloGramUnit = { 0, { 0, 1, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< kilogram [kg]*/
162 const LALUnit lalSecondUnit = { 0, { 0, 0, 1, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< second [s] */
163 const LALUnit lalAmpereUnit = { 0, { 0, 0, 0, 1, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Ampere [A] */
164 const LALUnit lalKelvinUnit = { 0, { 0, 0, 0, 0, 1, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Kelvin [K] */
165 const LALUnit lalStrainUnit = { 0, { 0, 0, 0, 0, 0, 1, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Strain [1] */
166 const LALUnit lalADCCountUnit = { 0, { 0, 0, 0, 0, 0, 0, 1}, { 0, 0, 0, 0, 0, 0, 0} }; /**< ADC count [count] */
167 /** @} */
168 
169 /** \name Derived Mechanical Units */
170 /** @{ */
171 const LALUnit lalHertzUnit = { 0, { 0, 0,-1, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Hertz [Hz] */
172 const LALUnit lalNewtonUnit = { 0, { 1, 1,-2, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Newton [N] */
173 const LALUnit lalPascalUnit = { 0, {-1, 1,-2, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Pascal [Pa] */
174 const LALUnit lalJouleUnit = { 0, { 2, 1,-2, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Joule [J] */
175 const LALUnit lalWattUnit = { 0, { 2, 1,-3, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Watt [W ] */
176 /** @} */
177 
178 /** \name Derived Electromagnetic Units */
179 /** @{ */
180 const LALUnit lalCoulombUnit = { 0, { 0, 0, 1, 1, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Coulomb [C] */
181 const LALUnit lalVoltUnit = { 0, { 2, 1,-3,-1, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Volt [V] */
182 const LALUnit lalOhmUnit = { 0, { 2, 1,-3,-2, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Ohm [\f$\Omega\f$] */
183 const LALUnit lalFaradUnit = { 0, {-2,-1, 4, 2, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Farad [F] */
184 const LALUnit lalWeberUnit = { 0, { 2, 1,-2,-1, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Weber [Wb] */
185 const LALUnit lalHenryUnit = { 0, { 2, 1,-2,-2, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Henry [H] */
186 const LALUnit lalTeslaUnit = { 0, { 0, 1,-2,-1, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Tesla [T] */
187 /** @} */
188 
189 /** \name Powers of Ten */
190 /** @{ */
191 const LALUnit lalYottaUnit = { 24, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Yotta [1e24] */
192 const LALUnit lalZettaUnit = { 21, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Zetta [1e21] */
193 const LALUnit lalExaUnit = { 18, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Exa [1e18] */
194 const LALUnit lalPetaUnit = { 15, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Peta [1e15] */
195 const LALUnit lalTeraUnit = { 12, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Tera [1e12] */
196 const LALUnit lalGigaUnit = { 9, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Giga [1e9] */
197 const LALUnit lalMegaUnit = { 6, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Mega [1e6] */
198 const LALUnit lalKiloUnit = { 3, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Kilo [1e3] */
199 const LALUnit lalHectoUnit = { 2, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Hecto [1e2] */
200 const LALUnit lalDekaUnit = { 1, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Deka [1e1] */
201 const LALUnit lalDeciUnit = { -1, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Deci [1e-1] */
202 const LALUnit lalCentiUnit = { -2, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Centi [1e-2] */
203 const LALUnit lalMilliUnit = { -3, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Milli [1e-3] */
204 const LALUnit lalMicroUnit = { -6, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Micro [1e-6] */
205 const LALUnit lalNanoUnit = { -9, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Nano [1e-9] */
206 const LALUnit lalPicoUnit = {-12, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Pico [1e-12] */
207 const LALUnit lalFemtoUnit = {-15, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Femto [1e-15] */
208 const LALUnit lalAttoUnit = {-18, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Atto [1e-18] */
209 const LALUnit lalZeptoUnit = {-21, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Zepto [1e-21] */
210 const LALUnit lalYoctoUnit = {-24, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Yocto [1e-24] */
211 /** @} */
212 
213 /** \name Convenient Scaled Units */
214 /** @{ */
215 const LALUnit lalGramUnit = { -3, { 0, 1, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Gram [1e-3] */
216 const LALUnit lalAttoStrainUnit = {-18, { 0, 0, 0, 0, 0, 1, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< AttoStrain [1e-18] */
217 const LALUnit lalPicoFaradUnit = {-12, {-2,-1, 2, 2, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< PicoFarad [1e-12 F] */
218 /** @} */
219 
220 /* Static function to read a number into a character array */
221 /* returns 0 on success, 1 on failure */
222 /* leaves *charPtrPtr pointing to first non-digit */
223 static int readNumber( char temp[], const char **charPtrPtr )
224 {
225  CHAR *tempPtr, *tempStopPtr;
226 
227  tempPtr = temp;
228  /* make sure we don't fall off end of temporary array */
229  tempStopPtr = temp + UNITDEFSC_TEMPSIZE;
230 
231  if ( ! isdigit(**charPtrPtr) ) return 1;
232 
233  do
234  {
235  *tempPtr = **charPtrPtr;
236  ++tempPtr, ++*charPtrPtr;
237  if (tempPtr >= tempStopPtr) return 1;
238  }
239  while ( isdigit(**charPtrPtr) );
240  *tempPtr = '\0';
241  return 0;
242 }
243 
244 /* Static function to read a string into a character array */
245 /* returns 0 on success, 1 on failure */
246 /* leaves *charPtrPtr pointing to first non-letter */
247 static int readString( char temp[UNITDEFSC_TEMPSIZE], const char **charPtrPtr )
248 {
249  CHAR *tempPtr, *tempStopPtr;
250 
251  tempPtr = temp;
252  /* make sure we don't fall off end of temporary array */
253  tempStopPtr = temp + UNITDEFSC_TEMPSIZE;
254 
255  if ( ! isalpha(**charPtrPtr) ) return 1;
256 
257  do
258  {
259  *tempPtr = **charPtrPtr;
260  ++tempPtr, ++*charPtrPtr;
261  if (tempPtr >= tempStopPtr) return 1;
262  }
263  while ( isalpha(**charPtrPtr) );
264  *tempPtr = '\0';
265  return 0;
266 }
267 
268 /**
269  * Returns the pointer to the input \c string, which
270  * is populated with the unit string if successful. If there is a failure,
271  * XLALUnitAsString() returns a \c NULL pointer and \c xlalErrno
272  * is set to one of the following values: \c XLAL_EFAULT if one of the
273  * input pointers is \c NULL or \c XLAL_EBADLEN if the length of the
274  * string is insufficent for the unit string.
275  */
276 char * XLALUnitAsString( char *string, UINT4 length, const LALUnit *input )
277 {
278  int n;
279  int i;
280  char *s = string;
281 
282  if ( ! string || ! input )
284  if ( ! length )
286 
287  *s = '\0';
288 
289  if (input->powerOfTen != 0)
290  {
291  n = snprintf(s, length, "10^%d", input->powerOfTen);
292  s += n;
293  length -= n;
294  if ( length <= 0 )
296  } /* if (input->powerOfTen != 0) */
297 
298  for (i=0; i<LALNumUnits; ++i)
299  {
300  const char *delim = (s != string) ? (const char*)" " : (const char*)"";
301  int numer = input->unitNumerator[i];
302  if (numer == 0)
303  continue;
304  if (input->unitDenominatorMinusOne[i] != 0)
305  {
306  n = snprintf(s, length, "%s%s^%d/%d", delim, lalUnitName[i], numer,
307  input->unitDenominatorMinusOne[i] + 1);
308  }
309  else if (numer == 1) /* denom == 0 */
310  {
311  n = snprintf(s, length, "%s%s", delim, lalUnitName[i]);
312  }
313  else /* numer != 1, denom == 0 */
314  {
315  n = snprintf(s, length, "%s%s^%d", delim, lalUnitName[i], numer);
316  }
317  s += n;
318  length -= n;
319  if ( length <= 0 )
321  } /* for (i=0; i<LALNumUnits; ++i) */
322 
323  return string;
324 }
325 
326 /**
327  * Allocates and returns a new string, which is populated with the unit
328  * string. If there is a failure, returns a \c NULL pointer and \c xlalErrno
329  * is set to one of the error values of \c XLALUnitAsString or \c XLALMalloc.
330  * Caller is responsible for freeing return value with \c XLALFree.
331  */
332 char * XLALUnitToString( const LALUnit *input )
333 {
334  char *output = NULL, *buf = XLALMalloc(LALUnitTextSize);
335  if (buf)
336  {
337  output = XLALUnitAsString(buf, LALUnitTextSize, input);
338  if (output)
339  output = XLALRealloc(buf, strlen(buf) + 1);
340  if (!output)
341  XLALFree(buf);
342  }
343  return output;
344 }
345 
346 /**
347  * Returns the pointer \c output upon return
348  * or a pointer to newly allocated memory if \c output was \c NULL;
349  * on failure, \c XLALParseUnitString() returns \c NULL and sets
350  * ::xlalErrno to one of the following values: #XLAL_ENOMEM
351  * if the routine was unable to allocate memory for the output or
352  * #XLAL_EFAILED if the routine was unable to parse the unit string.
353  */
354 LALUnit * XLALParseUnitString( LALUnit *output, const char *string )
355 {
356  UINT2 i;
357  INT2 sign;
358  CHAR temp[20];
359  int outputAllocated = 0;
360 
361  if ( ! output )
362  {
363  output = LALMalloc( sizeof( *output ) );
364  outputAllocated = 1;
365  if ( ! output )
367  }
368 
369  /* Start with dimensionless (all zeros) and fill in from there */
371 
372  /* If the string is NULL, it represents dimensionless */
373  if ( ! string )
374  return output;
375 
376  /* Strip leading whitespace */
377  string += strspn(string, "\t\n\v\f\r ");
378 
379  /* If the string is empty, it represents dimensionless */
380  if ( ! *string )
381  return output;
382 
383  /* Look for power of ten; note LALUnitsAsString is set up to say
384  * "10^1" rather than "10", so need not allow for missing '^'
385  */
386  if (*string == '1' && *(string+1) == '0' && *(string+2) == '^')
387  {
388  string += 3;
389  /* now pointing at first digit of power of ten (or minus sign) */
390 
391  if ( *string == '-' )
392  {
393  sign = -1;
394  ++string;
395  }
396  else
397  {
398  sign = 1;
399  }
400 
401  /* read power of ten into temp[]; return value of 1 means failure */
402  if ( readNumber( temp, &string ) )
403  {
404  if ( outputAllocated )
405  LALFree( output );
407  }
408  /* string now points to one after end of power of ten */
409 
410  output->powerOfTen = sign*atoi(temp);
411 
412  /* If the power of ten was all there was, return */
413  if (*string == '\0')
414  return output;
415 
416  if ( *string != ' ')
417  {
418  if ( outputAllocated )
419  LALFree( output );
421  }
422 
423  ++string;
424  } /* if (*string == '1' && *(string+1) == '0' && *(string+2) == '^') */
425 
426  /* string now points to start of first unit */
427 
428  /* Read units and exponents, one unit per pass of the following do loop */
429  do
430  {
431  /* read unit name into temp[]; return value of 1 means failure */
432  if ( readString( temp, &string ) )
433  {
434  if ( outputAllocated )
435  LALFree( output );
437  }
438 
439  /* string now points to one after end of unit name */
440 
441  /* find which unit name this matches */
442  for (i=0; i<LALNumUnits; ++i)
443  {
444  if (strcmp(temp,lalUnitName[i])==0)
445  break;
446  }
447  if (i>=LALNumUnits) /* didn't find it */
448  {
449  if ( outputAllocated )
450  LALFree( output );
452  }
453 
454  /* Make sure we haven't already read in this unit */
455  if ( output->unitNumerator[i] || output->unitDenominatorMinusOne[i] )
456  {
457  if ( outputAllocated )
458  LALFree( output );
460  }
461 
462  if ( *string == ' ' || *string == '\0' )
463  { /* We have only one power of the unit */
464  output->unitNumerator[i] = 1;
465  }
466  else if ( *string == '^' )
467  {
468  ++string;
469  /* now points to the first digit of the exponent, or minus sign */
470 
471  if ( *string == '-' )
472  {
473  sign = -1;
474  ++string;
475  }
476  else
477  {
478  sign = 1;
479  }
480 
481  /* read exponent numerator into temp[];
482  return value of 1 means failure */
483  if ( readNumber( temp, &string ) )
484  {
485  if ( outputAllocated )
486  LALFree( output );
488  }
489  output->unitNumerator[i] = sign * atoi(temp);
490 
491  if ( *string == '/' )
492  {
493  ++string;
494  /* now points to first digit of denominator */
495 
496  /* read exponent denominator into temp[];
497  return value of 1 means failure */
498  if ( readNumber( temp, &string ) || temp[0] == '0')
499  {
500  if ( outputAllocated )
501  LALFree( output );
503  }
504  output->unitDenominatorMinusOne[i] = atoi(temp) - 1;
505  } /* if ( *string == '/' ) */
506  } /* else if ( *string == '^' ) */
507  else
508  {
509  if ( outputAllocated )
510  LALFree( output );
512  }
513 
514  if ( *string == ' ') ++string;
515 
516  }
517  while ( *string != '\0' );
518 
519  return output;
520 }
521 
522 
523 /** @} *//* end: UnitDefs_c */
#define LALMalloc(n)
Definition: LALMalloc.h:93
#define LALFree(p)
Definition: LALMalloc.h:96
static int sign(int s)
Definition: LALStringTest.c:27
#define UNITDEFSC_TEMPSIZE
Definition: UnitDefs.c:25
int16_t INT2
Two-byte signed integer.
uint16_t UINT2
Two-byte unsigned integer.
char CHAR
One-byte signed integer, see Headers LAL(Atomic)Datatypes.h for more details.
uint32_t UINT4
Four-byte unsigned integer.
@ LALNumUnits
The number of units.
Definition: LALDatatypes.h:480
#define XLALMalloc(n)
Definition: LALMalloc.h:44
#define XLALFree(p)
Definition: LALMalloc.h:47
#define XLALRealloc(p, n)
Definition: LALMalloc.h:46
@ LALUnitNameSize
Definition: Units.h:171
@ LALUnitTextSize
Definition: Units.h:174
const LALUnit lalExaUnit
Exa [1e18].
Definition: UnitDefs.c:193
const LALUnit lalWattUnit
Watt [W ].
Definition: UnitDefs.c:175
const LALUnit lalKelvinUnit
Kelvin [K].
Definition: UnitDefs.c:164
const LALUnit lalHenryUnit
Henry [H].
Definition: UnitDefs.c:185
const LALUnit lalStrainUnit
Strain [1].
Definition: UnitDefs.c:165
const LALUnit lalWeberUnit
Weber [Wb].
Definition: UnitDefs.c:184
const LALUnit lalZeptoUnit
Zepto [1e-21].
Definition: UnitDefs.c:209
static int readString(char temp[UNITDEFSC_TEMPSIZE], const char **charPtrPtr)
Definition: UnitDefs.c:247
const LALUnit lalMicroUnit
Micro [1e-6].
Definition: UnitDefs.c:204
const LALUnit lalTeraUnit
Tera [1e12].
Definition: UnitDefs.c:195
const LALUnit lalDekaUnit
Deka [1e1].
Definition: UnitDefs.c:200
const LALUnit lalCentiUnit
Centi [1e-2].
Definition: UnitDefs.c:202
const LALUnit lalDeciUnit
Deci [1e-1].
Definition: UnitDefs.c:201
const LALUnit lalHectoUnit
Hecto [1e2].
Definition: UnitDefs.c:199
const LALUnit lalKiloGramUnit
kilogram [kg]
Definition: UnitDefs.c:161
const LALUnit lalNewtonUnit
Newton [N].
Definition: UnitDefs.c:172
const LALUnit lalAmpereUnit
Ampere [A].
Definition: UnitDefs.c:163
const LALUnit lalAttoStrainUnit
AttoStrain [1e-18].
Definition: UnitDefs.c:216
const LALUnit lalCoulombUnit
Coulomb [C].
Definition: UnitDefs.c:180
const LALUnit lalZettaUnit
Zetta [1e21].
Definition: UnitDefs.c:192
const LALUnit lalTeslaUnit
Tesla [T].
Definition: UnitDefs.c:186
const LALUnit lalSecondUnit
second [s]
Definition: UnitDefs.c:162
const LALUnit lalGigaUnit
Giga [1e9].
Definition: UnitDefs.c:196
const LALUnit lalGramUnit
Gram [1e-3].
Definition: UnitDefs.c:215
char * XLALUnitToString(const LALUnit *input)
Allocates and returns a new string, which is populated with the unit string.
Definition: UnitDefs.c:332
const LALUnit lalJouleUnit
Joule [J].
Definition: UnitDefs.c:174
const CHAR lalUnitName[LALNumUnits][LALUnitNameSize]
To convert a units structure to a string repesentation, we need to define the names of the basic unit...
Definition: UnitDefs.c:135
const LALUnit lalADCCountUnit
ADC count [count].
Definition: UnitDefs.c:166
const LALUnit lalHertzUnit
Hertz [Hz].
Definition: UnitDefs.c:171
const LALUnit lalMeterUnit
meter [m]
Definition: UnitDefs.c:160
const LALUnit lalPetaUnit
Peta [1e15].
Definition: UnitDefs.c:194
LALUnit * XLALParseUnitString(LALUnit *output, const char *string)
Returns the pointer output upon return or a pointer to newly allocated memory if output was NULL; on ...
Definition: UnitDefs.c:354
const LALUnit lalPicoFaradUnit
PicoFarad [1e-12 F].
Definition: UnitDefs.c:217
const LALUnit lalAttoUnit
Atto [1e-18].
Definition: UnitDefs.c:208
const LALUnit lalDimensionlessUnit
dimensionless units
Definition: UnitDefs.c:156
const LALUnit lalOhmUnit
Ohm [ ].
Definition: UnitDefs.c:182
const LALUnit lalKiloUnit
Kilo [1e3].
Definition: UnitDefs.c:198
const LALUnit lalVoltUnit
Volt [V].
Definition: UnitDefs.c:181
const LALUnit lalFemtoUnit
Femto [1e-15].
Definition: UnitDefs.c:207
const LALUnit lalPascalUnit
Pascal [Pa].
Definition: UnitDefs.c:173
const LALUnit lalMegaUnit
Mega [1e6].
Definition: UnitDefs.c:197
const LALUnit lalNanoUnit
Nano [1e-9].
Definition: UnitDefs.c:205
const LALUnit lalYoctoUnit
Yocto [1e-24].
Definition: UnitDefs.c:210
const LALUnit lalYottaUnit
Yotta [1e24].
Definition: UnitDefs.c:191
static int readNumber(char temp[], const char **charPtrPtr)
Definition: UnitDefs.c:223
const LALUnit lalFaradUnit
Farad [F].
Definition: UnitDefs.c:183
const LALUnit lalPicoUnit
Pico [1e-12].
Definition: UnitDefs.c:206
char * XLALUnitAsString(char *string, UINT4 length, const LALUnit *input)
Returns the pointer to the input string, which is populated with the unit string if successful.
Definition: UnitDefs.c:276
const LALUnit lalMilliUnit
Milli [1e-3].
Definition: UnitDefs.c:203
#define XLAL_ERROR_NULL(...)
Macro to invoke a failure from a XLAL routine returning a pointer.
Definition: XLALError.h:713
@ XLAL_EBADLEN
Inconsistent or invalid length.
Definition: XLALError.h:419
@ XLAL_ENOMEM
Memory allocation error.
Definition: XLALError.h:407
@ XLAL_EFAULT
Invalid pointer.
Definition: XLALError.h:408
@ XLAL_EFAILED
Generic failure.
Definition: XLALError.h:418
This structure stores units in the mksA system (plus Kelvin, Strain, and ADC Count).
Definition: LALDatatypes.h:498
INT2 powerOfTen
Overall power-of-ten scaling is 10^powerOfTen.
Definition: LALDatatypes.h:499
UINT2 unitDenominatorMinusOne[LALNumUnits]
Array of unit power denominators-minus-one.
Definition: LALDatatypes.h:501
INT2 unitNumerator[LALNumUnits]
Array of unit power numerators.
Definition: LALDatatypes.h:500
void output(int gps_sec, int output_type)
Definition: tconvert.c:440