Loading [MathJax]/extensions/TeX/AMSsymbols.js
LAL 7.7.0.1-3a66518
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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
156const 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/** @{ */
160const LALUnit lalMeterUnit = { 0, { 1, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< meter [m] */
161const LALUnit lalKiloGramUnit = { 0, { 0, 1, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< kilogram [kg]*/
162const LALUnit lalSecondUnit = { 0, { 0, 0, 1, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< second [s] */
163const LALUnit lalAmpereUnit = { 0, { 0, 0, 0, 1, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Ampere [A] */
164const LALUnit lalKelvinUnit = { 0, { 0, 0, 0, 0, 1, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Kelvin [K] */
165const LALUnit lalStrainUnit = { 0, { 0, 0, 0, 0, 0, 1, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Strain [1] */
166const 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/** @{ */
171const LALUnit lalHertzUnit = { 0, { 0, 0,-1, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Hertz [Hz] */
172const LALUnit lalNewtonUnit = { 0, { 1, 1,-2, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Newton [N] */
173const LALUnit lalPascalUnit = { 0, {-1, 1,-2, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Pascal [Pa] */
174const LALUnit lalJouleUnit = { 0, { 2, 1,-2, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Joule [J] */
175const 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/** @{ */
180const LALUnit lalCoulombUnit = { 0, { 0, 0, 1, 1, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Coulomb [C] */
181const LALUnit lalVoltUnit = { 0, { 2, 1,-3,-1, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Volt [V] */
182const LALUnit lalOhmUnit = { 0, { 2, 1,-3,-2, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Ohm [\f$\Omega\f$] */
183const LALUnit lalFaradUnit = { 0, {-2,-1, 4, 2, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Farad [F] */
184const LALUnit lalWeberUnit = { 0, { 2, 1,-2,-1, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Weber [Wb] */
185const LALUnit lalHenryUnit = { 0, { 2, 1,-2,-2, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Henry [H] */
186const 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/** @{ */
191const LALUnit lalYottaUnit = { 24, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Yotta [1e24] */
192const LALUnit lalZettaUnit = { 21, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Zetta [1e21] */
193const LALUnit lalExaUnit = { 18, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Exa [1e18] */
194const LALUnit lalPetaUnit = { 15, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Peta [1e15] */
195const LALUnit lalTeraUnit = { 12, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Tera [1e12] */
196const LALUnit lalGigaUnit = { 9, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Giga [1e9] */
197const LALUnit lalMegaUnit = { 6, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Mega [1e6] */
198const LALUnit lalKiloUnit = { 3, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Kilo [1e3] */
199const LALUnit lalHectoUnit = { 2, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Hecto [1e2] */
200const LALUnit lalDekaUnit = { 1, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Deka [1e1] */
201const LALUnit lalDeciUnit = { -1, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Deci [1e-1] */
202const LALUnit lalCentiUnit = { -2, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Centi [1e-2] */
203const LALUnit lalMilliUnit = { -3, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Milli [1e-3] */
204const LALUnit lalMicroUnit = { -6, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Micro [1e-6] */
205const LALUnit lalNanoUnit = { -9, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Nano [1e-9] */
206const LALUnit lalPicoUnit = {-12, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Pico [1e-12] */
207const LALUnit lalFemtoUnit = {-15, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Femto [1e-15] */
208const LALUnit lalAttoUnit = {-18, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Atto [1e-18] */
209const LALUnit lalZeptoUnit = {-21, { 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Zepto [1e-21] */
210const 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/** @{ */
215const LALUnit lalGramUnit = { -3, { 0, 1, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< Gram [1e-3] */
216const LALUnit lalAttoStrainUnit = {-18, { 0, 0, 0, 0, 0, 1, 0}, { 0, 0, 0, 0, 0, 0, 0} }; /**< AttoStrain [1e-18] */
217const 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 */
223static 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 */
247static 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 */
276char * 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 */
332char * XLALUnitToString( const LALUnit *input )
333{
334 char *output = NULL, *buf = XLALMalloc(LALUnitTextSize);
335 if (buf)
336 {
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 */
354LALUnit * 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
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 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
char * XLALUnitToString(const LALUnit *input)
Allocates and returns a new string, which is populated with the unit string.
Definition: UnitDefs.c:332
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
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 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
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
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
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