/usr/include/udunits2.h is in libudunits2-dev 2.2.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 | /*
* Copyright 2013 University Corporation for Atmospheric Research
*
* This file is part of the UDUNITS-2 package. See the file COPYRIGHT
* in the top-level source-directory of the package for copying and
* redistribution conditions.
*/
#ifndef UT_UNITS2_H_INCLUDED
#define UT_UNITS2_H_INCLUDED
#include <stdarg.h>
#include <stddef.h>
#include "converter.h"
typedef struct ut_system ut_system;
typedef union ut_unit ut_unit;
enum utStatus {
UT_SUCCESS = 0, /* Success */
UT_BAD_ARG, /* An argument violates the function's contract */
UT_EXISTS, /* Unit, prefix, or identifier already exists */
UT_NO_UNIT, /* No such unit exists */
UT_OS, /* Operating-system error. See "errno". */
UT_NOT_SAME_SYSTEM, /* The units belong to different unit-systems */
UT_MEANINGLESS, /* The operation on the unit(s) is meaningless */
UT_NO_SECOND, /* The unit-system doesn't have a unit named "second" */
UT_VISIT_ERROR, /* An error occurred while visiting a unit */
UT_CANT_FORMAT, /* A unit can't be formatted in the desired manner */
UT_SYNTAX, /* string unit representation contains syntax error */
UT_UNKNOWN, /* string unit representation contains unknown word */
UT_OPEN_ARG, /* Can't open argument-specified unit database */
UT_OPEN_ENV, /* Can't open environment-specified unit database */
UT_OPEN_DEFAULT, /* Can't open installed, default, unit database */
UT_PARSE /* Error parsing unit specification */
};
typedef enum utStatus ut_status;
enum utEncoding {
UT_ASCII = 0,
UT_ISO_8859_1 = 1,
UT_LATIN1 = UT_ISO_8859_1,
UT_UTF8 = 2
};
typedef enum utEncoding ut_encoding;
#define UT_NAMES 4
#define UT_DEFINITION 8
/*
* Data-structure for a visitor to a unit:
*/
typedef struct ut_visitor {
/*
* Visits a basic-unit. A basic-unit is a base unit like "meter" or a non-
* dimensional but named unit like "radian".
*
* Arguments:
* unit Pointer to the basic-unit.
* arg Client pointer passed to ut_accept_visitor().
* Returns:
* UT_SUCCESS Success.
* else Failure.
*/
ut_status (*visit_basic)(const ut_unit* unit, void* arg);
/*
* Visits a product-unit. A product-unit is a product of zero or more
* basic-units, each raised to a non-zero power.
*
* Arguments:
* unit Pointer to the product-unit.
* count The number of basic-units in the product. May be zero.
* basicUnits Pointer to an array of basic-units in the product.
* powers Pointer to an array of powers to which the respective
* basic-units are raised.
* arg Client pointer passed to ut_accept_visitor().
* Returns:
* UT_SUCCESS Success.
* else Failure.
*/
ut_status (*visit_product)(const ut_unit* unit, int count,
const ut_unit* const* basicUnits, const int* powers, void* arg);
/*
* Visits a Galilean-unit. A Galilean-unit has an underlying unit and a
* non-unity scale factor or a non-zero offset.
*
* Arguments:
* unit Pointer to the Galilean-unit.
* scale The scale factor (e.g., 1000 for a kilometer when the
* underlying unit is a meter).
* underlyingUnit Pointer to the underlying unit.
* offset Pointer to the underlying unit.
* arg Client pointer passed to ut_accept_visitor().
* Returns:
* UT_SUCCESS Success.
* else Failure.
*/
ut_status (*visit_galilean)(const ut_unit* unit, double scale,
const ut_unit* underlyingUnit, double offset, void* arg);
/*
* Visits a timestamp-unit. A timestamp-unit has an underlying unit of time
* and an encoded time-origin.
*
* Arguments:
* unit Pointer to the timestamp-unit.
* timeUnit Pointer to the underlying unit of time.
* origin Encoded origin of the timestamp-unit.
* arg Client pointer passed to ut_accept_visitor().
* Returns:
* UT_SUCCESS Success.
* else Failure.
*/
ut_status (*visit_timestamp)(const ut_unit* unit,
const ut_unit* timeUnit, double origin, void* arg);
/*
* Visits a logarithmic-unit. A logarithmic-unit has a logarithmic base and
* a unit that specifies the reference level.
*
* Arguments:
* unit Pointer to the logarithmic-unit.
* base The logarithmic base (e.g., 2, M_E, 10).
* reference Pointer to the unit that specifies the reference level.
* arg Client pointer passed to ut_accept_visitor().
* Returns:
* UT_SUCCESS Success.
* else Failure.
*/
ut_status (*visit_logarithmic)(const ut_unit* unit, double base,
const ut_unit* reference, void* arg);
} ut_visitor;
typedef int (*ut_error_message_handler)(const char* fmt, va_list args);
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************************************
* Unit System:
******************************************************************************/
/**
* Returns the pathname of the XML database.
*
* @param path The pathname of the XML file or NULL.
* @param status Status. One of UT_OPEN_ARG, UT_OPEN_ENV, or UT_OPEN_DEFAULT.
* @return If "path" is not NULL, then it is returned; otherwise, the
* pathname specified by the environment variable
* UDUNITS2_XML_PATH is returned if set; otherwise, the
* compile-time pathname of the installed, default, unit
* database is returned.
*/
const char*
ut_get_path_xml(
const char* path,
ut_status* status);
/*
* Returns the unit-system corresponding to an XML file. This is the usual way
* that a client will obtain a unit-system.
*
* Arguments:
* path The pathname of the XML file or NULL. If NULL, then the
* pathname specified by the environment variable UDUNITS2_XML_PATH
* is used if set; otherwise, the compile-time pathname of the
* installed, default, unit database is used.
* Returns:
* NULL Failure. "ut_get_status()" will be
* UT_OPEN_ARG "path" is non-NULL but file couldn't be
* opened. See "errno" for reason.
* UT_OPEN_ENV "path" is NULL and environment variable
* UDUNITS2_XML_PATH is set but file
* couldn't be opened. See "errno" for
* reason.
* UT_OPEN_DEFAULT "path" is NULL, environment variable
* UDUNITS2_XML_PATH is unset, and the
* installed, default, unit database
* couldn't be opened. See "errno" for
* reason.
* UT_PARSE Couldn't parse unit database.
* UT_OS Operating-system error. See "errno".
* else Pointer to the unit-system defined by "path".
*/
ut_system*
ut_read_xml(
const char* path);
/*
* Returns a new unit-system. On success, the unit-system will only contain
* the dimensionless unit one. See "ut_get_dimensionless_unit_one()".
*
* Returns:
* NULL Failure. "ut_get_status()" will be:
* UT_OS Operating-system error. See "errno".
* else Pointer to a new unit system.
*/
ut_system*
ut_new_system(void);
/*
* Frees a unit-system. All unit-to-identifier and identifier-to-unit mappings
* will be removed.
*
* Arguments:
* system Pointer to the unit-system to be freed. Use of "system"
* upon return results in undefined behavior.
*/
void
ut_free_system(
ut_system* system);
/*
* Returns the unit-system to which a unit belongs.
*
* Arguments:
* unit Pointer to the unit in question.
* Returns:
* NULL Failure. "ut_get_status()" will be
* UT_BAD_ARG "unit" is NULL.
* else Pointer to the unit-system to which "unit" belongs.
*/
ut_system*
ut_get_system(
const ut_unit* const unit);
/*
* Returns the dimensionless-unit one of a unit-system.
*
* Arguments:
* system Pointer to the unit-system for which the dimensionless-unit one
* will be returned.
* Returns:
* NULL Failure. "ut_get_status()" will be:
* UT_BAD_ARG "system" is NULL.
* else Pointer to the dimensionless-unit one associated with "system".
* While not necessary, the pointer may be passed to ut_free()
* when the unit is no longer needed by the client.
*/
ut_unit*
ut_get_dimensionless_unit_one(
const ut_system* const system);
/*
* Returns the unit with a given name from a unit-system. Name comparisons
* are case-insensitive.
*
* Arguments:
* system Pointer to the unit-system.
* name Pointer to the name of the unit to be returned.
* Returns:
* NULL Failure. "ut_get_status()" will be
* UT_SUCCESS "name" doesn't map to a unit of
* "system".
* UT_BAD_ARG "system" or "name" is NULL.
* else Pointer to the unit of the unit-system with the given name.
* The pointer should be passed to ut_free() when the unit is
* no longer needed.
*/
ut_unit*
ut_get_unit_by_name(
const ut_system* const system,
const char* const name);
/*
* Returns the unit with a given symbol from a unit-system. Symbol
* comparisons are case-sensitive.
*
* Arguments:
* system Pointer to the unit-system.
* symbol Pointer to the symbol associated with the unit to be
* returned.
* Returns:
* NULL Failure. "ut_get_status()" will be
* UT_SUCCESS "symbol" doesn't map to a unit of
* "system".
* UT_BAD_ARG "system" or "symbol" is NULL.
* else Pointer to the unit in the unit-system with the given symbol.
* The pointer should be passed to ut_free() when the unit is no
* longer needed.
*/
ut_unit*
ut_get_unit_by_symbol(
const ut_system* const system,
const char* const symbol);
/*
* Sets the "second" unit of a unit-system. This function must be called before
* the first call to "ut_offset_by_time()". ut_read_xml() calls this function if the
* resulting unit-system contains a unit named "second".
*
* Arguments:
* second Pointer to the "second" unit.
* Returns:
* UT_BAD_ARG "second" is NULL.
* UT_EXISTS The second unit of the unit-system to which "second"
* belongs is set to a different unit.
* UT_SUCCESS Success.
*/
ut_status
ut_set_second(
const ut_unit* const second);
/******************************************************************************
* Defining Unit Prefixes:
******************************************************************************/
/*
* Adds a name-prefix to a unit-system. A name-prefix is something like "mega"
* or "milli". Comparisons between name-prefixes are case-insensitive.
*
* Arguments:
* system Pointer to the unit-system.
* name Pointer to the name-prefix (e.g., "mega"). May be freed
* upon return.
* value The value of the prefix (e.g., 1e6).
* Returns:
* UT_SUCCESS Success.
* UT_BAD_ARG "system" or "name" is NULL, or "value" is 0.
* UT_EXISTS "name" already maps to a different value.
* UT_OS Operating-system failure. See "errno".
*/
ut_status
ut_add_name_prefix(
ut_system* const system,
const char* const name,
const double value);
/*
* Adds a symbol-prefix to a unit-system. A symbol-prefix is something like
* "M" or "y". Comparisons between symbol-prefixes are case-sensitive.
*
* Arguments:
* system Pointer to the unit-system.
* symbol Pointer to the symbol-prefix (e.g., "M"). May be freed
* upon return.
* value The value of the prefix (e.g., 1e6).
* Returns:
* UT_SUCCESS Success.
* UT_BADSYSTEM "system" or "symbol" is NULL.
* UT_BAD_ARG "value" is 0.
* UT_EXISTS "symbol" already maps to a different value.
* UT_OS Operating-system failure. See "errno".
*/
ut_status
ut_add_symbol_prefix(
ut_system* const system,
const char* const symbol,
const double value);
/******************************************************************************
* Defining and Deleting Units:
******************************************************************************/
/*
* Adds a base-unit to a unit-system. Clients that use ut_read_xml() should not
* normally need to call this function.
*
* Arguments:
* system Pointer to the unit-system to which to add the new base-unit.
* Returns:
* NULL Failure. "ut_get_status()" will be
* UT_BAD_ARG "system" or "name" is NULL.
* UT_OS Operating-system error. See "errno".
* else Pointer to the new base-unit. The pointer should be passed to
* ut_free() when the unit is no longer needed by the client (the
* unit will remain in the unit-system).
*/
ut_unit*
ut_new_base_unit(
ut_system* const system);
/*
* Adds a dimensionless-unit to a unit-system. In the SI system of units, the
* derived-unit radian is a dimensionless-unit. Clients that use ut_read_xml()
* should not normally need to call this function.
*
* Arguments:
* system Pointer to the unit-system to which to add the new
* dimensionless-unit.
* Returns:
* NULL Failure. "ut_get_status()" will be
* UT_BAD_ARG "system" is NULL.
* UT_OS Operating-system error. See "errno".
* else Pointer to the new dimensionless-unit. The pointer should be
* passed to ut_free() when the unit is no longer needed by the
* client (the unit will remain in the unit-system).
*/
ut_unit*
ut_new_dimensionless_unit(
ut_system* const system);
/*
* Returns a clone of a unit.
*
* Arguments:
* unit Pointer to the unit to be cloned.
* Returns:
* NULL Failure. ut_get_status() will be
* UT_OS Operating-system failure. See "errno".
* UT_BAD_ARG "unit" is NULL.
* else Pointer to the clone of "unit". The pointer should be
* passed to ut_free() when the unit is no longer needed by the
* client.
*/
ut_unit*
ut_clone(
const ut_unit* unit);
/*
* Frees resources associated with a unit. This function should be invoked on
* all units that are no longer needed by the client. Use of the unit upon
* return from this function will result in undefined behavior.
*
* Arguments:
* unit Pointer to the unit to have its resources freed or NULL.
*/
void
ut_free(
ut_unit* const unit);
/******************************************************************************
* Mapping between Units and Names:
******************************************************************************/
/*
* Returns the name in a given encoding to which a unit maps.
*
* Arguments:
* unit Pointer to the unit whose name should be returned.
* encoding The desired encoding of the name.
* Returns:
* NULL Failure. "ut_get_status()" will be
* UT_BAD_ARG "unit" is NULL.
* UT_SUCCESS "unit" doesn't map to a name in
* in the given encoding.
* else Pointer to the name in the given encoding to which
* "unit" maps.
*/
const char*
ut_get_name(
const ut_unit* const unit,
const ut_encoding encoding);
/*
* Adds a mapping from a name to a unit.
*
* Arguments:
* name Pointer to the name to be mapped to "unit". May be
* freed upon return.
* encoding The character encoding of "name".
* unit Pointer to the unit to be mapped-to by "name". May be
* freed upon return.
* Returns:
* UT_BAD_ARG "name" or "unit" is NULL.
* UT_OS Operating-system error. See "errno".
* UT_EXISTS "name" already maps to a different unit.
* UT_SUCCESS Success.
*/
ut_status
ut_map_name_to_unit(
const char* const name,
const ut_encoding encoding,
const ut_unit* const unit);
/*
* Removes a mapping from a name to a unit. After this function,
* ut_get_unit_by_name(system,name) will no longer return a unit.
*
* Arguments:
* system The unit-system to which the unit belongs.
* name The name of the unit.
* encoding The character encoding of "name".
* Returns:
* UT_SUCCESS Success.
* UT_BAD_ARG "system" or "name" is NULL.
*/
ut_status
ut_unmap_name_to_unit(
ut_system* system,
const char* const name,
const ut_encoding encoding);
/*
* Adds a mapping from a unit to a name.
*
* Arguments:
* unit Pointer to the unit to be mapped to "name". May be
* freed upon return.
* name Pointer to the name to be mapped-to by "unit". May be
* freed upon return.
* encoding The encoding of "name".
* Returns:
* UT_SUCCESS Success.
* UT_BAD_ARG "unit" or "name" is NULL, or "name" is not in the
* specified encoding.
* UT_OS Operating-system error. See "errno".
* UT_EXISTS "unit" already maps to a name.
*/
ut_status
ut_map_unit_to_name(
const ut_unit* const unit,
const char* const name,
ut_encoding encoding);
/*
* Removes a mapping from a unit to a name.
*
* Arguments:
* unit Pointer to the unit. May be freed upon return.
* encoding The encoding to be removed. No other encodings will be
* removed.
* Returns:
* UT_BAD_ARG "unit" is NULL.
* UT_SUCCESS Success.
*/
ut_status
ut_unmap_unit_to_name(
const ut_unit* const unit,
ut_encoding encoding);
/******************************************************************************
* Mapping between Units and Symbols:
******************************************************************************/
/*
* Returns the symbol in a given encoding to which a unit maps.
*
* Arguments:
* unit Pointer to the unit whose symbol should be returned.
* encoding The desired encoding of the symbol.
* Returns:
* NULL Failure. "ut_get_status()" will be
* UT_BAD_ARG "unit" is NULL.
* UT_SUCCESS "unit" doesn't map to a symbol
* in the given encoding.
* else Pointer to the symbol in the given encoding to which
* "unit" maps.
*/
const char*
ut_get_symbol(
const ut_unit* const unit,
const ut_encoding encoding);
/*
* Adds a mapping from a symbol to a unit.
*
* Arguments:
* symbol Pointer to the symbol to be mapped to "unit". May be
* freed upon return.
* ut_encoding The character encoding of "symbol".
* unit Pointer to the unit to be mapped-to by "symbol". May
* be freed upon return.
* Returns:
* UT_BAD_ARG "symbol" or "unit" is NULL.
* UT_OS Operating-system error. See "errno".
* UT_EXISTS "symbol" already maps to a different unit.
* UT_SUCCESS Success.
*/
ut_status
ut_map_symbol_to_unit(
const char* const symbol,
const ut_encoding encoding,
const ut_unit* const unit);
/*
* Removes a mapping from a symbol to a unit. After this function,
* ut_get_unit_by_symbol(system,symbol) will no longer return a unit.
*
* Arguments:
* system The unit-system to which the unit belongs.
* symbol The symbol of the unit.
* encoding The character encoding of "symbol".
* Returns:
* UT_SUCCESS Success.
* UT_BAD_ARG "system" or "symbol" is NULL.
*/
ut_status
ut_unmap_symbol_to_unit(
ut_system* system,
const char* const symbol,
const ut_encoding encoding);
/*
* Adds a mapping from a unit to a symbol.
*
* Arguments:
* unit Pointer to the unit to be mapped to "symbol". May be
* freed upon return.
* symbol Pointer to the symbol to be mapped-to by "unit". May
* be freed upon return.
* encoding The encoding of "symbol".
* Returns:
* UT_SUCCESS Success.
* UT_BAD_ARG "unit" or "symbol" is NULL.
* UT_OS Operating-system error. See "errno".
* UT_EXISTS "unit" already maps to a symbol.
*/
ut_status
ut_map_unit_to_symbol(
const ut_unit* unit,
const char* const symbol,
ut_encoding encoding);
/*
* Removes a mapping from a unit to a symbol.
*
* Arguments:
* unit Pointer to the unit to be unmapped to a symbol. May be
* freed upon return.
* encoding The encoding to be removed. The mappings for "unit" in
* other encodings will not be removed.
* Returns:
* UT_SUCCESS Success.
* UT_BAD_ARG "unit" is NULL.
*/
ut_status
ut_unmap_unit_to_symbol(
const ut_unit* const unit,
ut_encoding encoding);
/******************************************************************************
* Getting Information about a Unit:
******************************************************************************/
/*
* Indicates if a given unit is dimensionless or not. Note that logarithmic
* units are dimensionless by definition.
*
* Arguments:
* unit Pointer to the unit in question.
* Returns:
* 0 "unit" is dimensionfull or an error occurred. "ut_get_status()"
* will be
* UT_BAD_ARG "unit" is NULL.
* UT_SUCCESS "unit" is dimensionfull.
* else "unit" is dimensionless.
*/
int
ut_is_dimensionless(
const ut_unit* const unit);
/*
* Indicates if two units belong to the same unit-system.
*
* Arguments:
* unit1 Pointer to a unit.
* unit2 Pointer to another unit.
* Returns:
* 0 Failure or the units belong to different unit-systems.
* "ut_get_status()" will be
* UT_BAD_ARG "unit1" or "unit2" is NULL.
* UT_SUCCESS The units belong to different
* unit-systems.
* else The units belong to the same unit-system.
*/
int
ut_same_system(
const ut_unit* const unit1,
const ut_unit* const unit2);
/*
* Compares two units. Returns a value less than, equal to, or greater than
* zero as the first unit is considered less than, equal to, or greater than
* the second unit, respectively. Units from different unit-systems never
* compare equal.
*
* Arguments:
* unit1 Pointer to a unit or NULL.
* unit2 Pointer to another unit or NULL.
* Returns:
* <0 The first unit is less than the second unit.
* 0 The first and second units are equal or both units are NULL.
* >0 The first unit is greater than the second unit.
*/
int
ut_compare(
const ut_unit* const unit1,
const ut_unit* const unit2);
/*
* Indicates if numeric values in one unit are convertible to numeric values in
* another unit via "ut_get_converter()". In making this determination,
* dimensionless units are ignored.
*
* Arguments:
* unit1 Pointer to a unit.
* unit2 Pointer to another unit.
* Returns:
* 0 Failure. "ut_get_status()" will be
* UT_BAD_ARG "unit1" or "unit2" is NULL.
* UT_NOT_SAME_SYSTEM "unit1" and "unit2" belong to
* different unit-sytems.
* UT_SUCCESS Conversion between the units is
* not possible (e.g., "unit1" is
* "meter" and "unit2" is
* "kilogram").
* else Numeric values can be converted between the units.
*/
int
ut_are_convertible(
const ut_unit* const unit1,
const ut_unit* const unit2);
/*
* Returns a converter of numeric values in one unit to numeric values in
* another unit. The returned converter should be passed to cv_free() when it is
* no longer needed by the client.
*
* NOTE: Leap seconds are not taken into account when converting between
* timestamp units.
*
* Arguments:
* from Pointer to the unit from which to convert values.
* to Pointer to the unit to which to convert values.
* Returns:
* NULL Failure. "ut_get_status()" will be:
* UT_BAD_ARG "from" or "to" is NULL.
* UT_NOT_SAME_SYSTEM "from" and "to" belong to
* different unit-systems.
* UT_MEANINGLESS Conversion between the units is
* not possible. See
* "ut_are_convertible()".
* else Pointer to the appropriate converter. The pointer
* should be passed to cv_free() when no longer needed by
* the client.
*/
cv_converter*
ut_get_converter(
ut_unit* const from,
ut_unit* const to);
/******************************************************************************
* Arithmetic Unit Manipulation:
******************************************************************************/
/*
* Returns a unit equivalent to another unit scaled by a numeric factor,
* e.g.,
* const ut_unit* meter = ...
* const ut_unit* kilometer = ut_scale(1000, meter);
*
* Arguments:
* factor The numeric scale factor.
* unit Pointer to the unit to be scaled.
* Returns:
* NULL Failure. "ut_get_status()" will be
* UT_BAD_ARG "factor" is 0 or "unit" is NULL.
* UT_OS Operating-system error. See
* "errno".
* else Pointer to the resulting unit. The pointer should be
* passed to ut_free() when the unit is no longer needed by
* the client.
*/
ut_unit*
ut_scale(
const double factor,
const ut_unit* const unit);
/*
* Returns a unit equivalent to another unit offset by a numeric amount,
* e.g.,
* const ut_unit* kelvin = ...
* const ut_unit* celsius = ut_offset(kelvin, 273.15);
*
* Arguments:
* unit Pointer to the unit to be offset.
* offset The numeric offset.
* Returns:
* NULL Failure. "ut_get_status()" will be
* UT_BAD_ARG "unit" is NULL.
* UT_OS Operating-system error. See
* "errno".
* else Pointer to the resulting unit. The pointer should be
* passed to ut_free() when the unit is no longer needed by
* the client.
*/
ut_unit*
ut_offset(
const ut_unit* const unit,
const double offset);
/*
* Returns a unit equivalent to another unit relative to a particular time.
* e.g.,
* const ut_unit* second = ...
* const ut_unit* secondsSinceTheEpoch =
* ut_offset_by_time(second, ut_encode_time(1970, 1, 1, 0, 0, 0.0));
*
* Arguments:
* unit Pointer to the time-unit to be made relative to a time-origin.
* origin The origin as returned by ut_encode_time().
* Returns:
* NULL Failure. "ut_get_status()" will be
* UT_BAD_ARG "unit" is NULL.
* UT_OS Operating-system error. See "errno".
* UT_MEANINGLESS Creation of a timestamp unit based on
* "unit" is not meaningful.
* UT_NO_SECOND The associated unit-system doesn't
* contain a "second" unit. See
* ut_set_second().
* else Pointer to the resulting unit. The pointer should be passed
* to ut_free() when the unit is no longer needed by the client.
*/
ut_unit*
ut_offset_by_time(
const ut_unit* const unit,
const double origin);
/*
* Returns the result of multiplying one unit by another unit.
*
* Arguments:
* unit1 Pointer to a unit.
* unit2 Pointer to another unit.
* Returns:
* NULL Failure. "ut_get_status()" will be:
* UT_BAD_ARG "unit1" or "unit2" is NULL.
* UT_NOT_SAME_SYSTEM "unit1" and "unit2" belong to
* different unit-systems.
* UT_OS Operating-system error. See "errno".
* else Pointer to the resulting unit. The pointer should be passed
* to ut_free() when the unit is no longer needed by the client.
*/
ut_unit*
ut_multiply(
const ut_unit* const unit1,
const ut_unit* const unit2);
/*
* Returns the inverse (i.e., reciprocal) of a unit. This convenience function
* is equal to "ut_raise(unit, -1)".
*
* Arguments:
* unit Pointer to the unit.
* Returns:
* NULL Failure. "ut_get_status()" will be:
* UT_BAD_ARG "unit" is NULL.
* UT_OS Operating-system error. See "errno".
* else Pointer to the resulting unit. The pointer should be passed to
* ut_free() when the unit is no longer needed by the client.
*/
ut_unit*
ut_invert(
const ut_unit* const unit);
/*
* Returns the result of dividing one unit by another unit. This convenience
* function is equivalent to the following sequence:
* {
* ut_unit* inverse = ut_invert(denom);
* ut_multiply(numer, inverse);
* ut_free(inverse);
* }
*
* Arguments:
* numer Pointer to the numerator (top, dividend) unit.
* denom Pointer to the denominator (bottom, divisor) unit.
* Returns:
* NULL Failure. "ut_get_status()" will be:
* UT_BAD_ARG "numer" or "denom" is NULL.
* UT_NOT_SAME_SYSTEM "unit1" and "unit2" belong to
* different unit-systems.
* UT_OS Operating-system error. See "errno".
* else Pointer to the resulting unit. The pointer should be passed to
* ut_free() when the unit is no longer needed by the client.
*/
ut_unit*
ut_divide(
const ut_unit* const numer,
const ut_unit* const denom);
/*
* Returns the result of raising a unit to a power.
*
* Arguments:
* unit Pointer to the unit.
* power The power by which to raise "unit". Must be greater than or
* equal to -255 and less than or equal to 255.
* Returns:
* NULL Failure. "ut_get_status()" will be:
* UT_BAD_ARG "unit" is NULL or "power" is invalid.
* UT_OS Operating-system error. See "errno".
* else Pointer to the resulting unit. The pointer should be passed to
* ut_free() when the unit is no longer needed by the client.
*/
ut_unit*
ut_raise(
const ut_unit* const unit,
const int power);
/*
* Returns the result of taking the root of a unit.
*
* Arguments:
* unit Pointer to the unit.
* root The root to take of "unit". Must be greater than or
* equal to 1 and less than or equal to 255.
* Returns:
* NULL Failure. "ut_get_status()" will be:
* UT_BAD_ARG "unit" is NULL, or "root" is invalid.
* In particular, all powers of base units
* in "unit" must be integral multiples of
* "root".
* UT_OS Operating-system error. See "errno".
* else Pointer to the resulting unit. The pointer should be passed to
* ut_free() when the unit is no longer needed by the client.
*/
ut_unit*
ut_root(
const ut_unit* const unit,
const int root);
/*
* Returns the logarithmic unit corresponding to a logarithmic base and a
* reference level. For example, the following creates a decibel unit with a
* one milliwatt reference level:
*
* const ut_unit* watt = ...;
* const ut_unit* milliWatt = ut_scale(0.001, watt);
*
* if (milliWatt != NULL) {
* const ut_unit* bel_1_mW = ut_log(10.0, milliWatt);
*
* if (bel_1_mW != NULL) {
* const ut_unit* decibel_1_mW = ut_scale(0.1, bel_1_mW);
*
* if (decibel_1_mW != NULL) {
* ...
* ut_free(decibel_1_mW);
* } // "decibel_1_mW" allocated
*
* ut_free(bel_1_mW);
* } // "bel_1_mW" allocated
*
* ut_free(milliWatt);
* } // "milliWatt" allocated
*
* Arguments:
* base The logarithmic base (e.g., 2, M_E, 10). Must be
* greater than one. "M_E" is defined in <math.h>.
* reference Pointer to the reference value as a unit.
* Returns:
* NULL Failure. "ut_get_status()" will be:
* UT_BAD_ARG "base" is invalid or "reference"
* is NULL.
* UT_OS Operating-system error. See
* "errno".
* else Pointer to the resulting unit. The pointer should be
* passed to ut_free() when the unit is no longer needed by
* the client.
*/
ut_unit*
ut_log(
const double base,
const ut_unit* const reference);
/******************************************************************************
* Parsing and Formatting Units:
******************************************************************************/
/*
* Returns the binary representation of a unit corresponding to a string
* representation.
*
* Arguments:
* system Pointer to the unit-system in which the parsing will
* occur.
* string The string to be parsed (e.g., "millimeters"). There
* should be no leading or trailing whitespace in the
* string. See ut_trim().
* encoding The encoding of "string".
* Returns:
* NULL Failure. "ut_get_status()" will be one of
* UT_BAD_ARG "system" or "string" is NULL.
* UT_SYNTAX "string" contained a syntax
* error.
* UT_UNKNOWN "string" contained an unknown
* identifier.
* UT_OS Operating-system failure. See
* "errno".
* else Pointer to the unit corresponding to "string".
*/
ut_unit*
ut_parse(
const ut_system* const system,
const char* const string,
const ut_encoding encoding);
/*
* Removes leading and trailing whitespace from a string.
*
* Arguments:
* string NUL-terminated string. Will be modified if it contains
* whitespace..
* encoding The character-encoding of "string".
* Returns:
* "string", with all leading and trailing whitespace removed.
*/
char*
ut_trim(
char* const string,
const ut_encoding encoding);
/*
* Formats a unit.
*
* Arguments:
* unit Pointer to the unit to be formatted.
* buf Pointer to the buffer into which to format "unit".
* size Size of the buffer in bytes.
* opts Formatting options: bitwise-OR of zero or more of the
* following:
* UT_NAMES Use unit names instead of
* symbols
* UT_DEFINITION The formatted string should be
* the definition of "unit" in
* terms of basic-units instead of
* stopping any expansion at the
* highest level possible.
* UT_ASCII The string should be formatted
* using the ASCII character set
* (default).
* UT_LATIN1 The string should be formatted
* using the ISO Latin-1 (alias
* ISO-8859-1) character set.
* UT_UTF8 The string should be formatted
* using the UTF-8 character set.
* UT_LATIN1 and UT_UTF8 are mutually exclusive: they may
* not both be specified.
* Returns:
* -1 Failure: "ut_get_status()" will be
* UT_BAD_ARG "unit" or "buf" is NULL, or both
* UT_LATIN1 and UT_UTF8 specified.
* UT_CANT_FORMAT "unit" can't be formatted in
* the desired manner.
* else Success. Number of characters printed in "buf". If
* the number is equal to the size of the buffer, then the
* buffer is too small to have a terminating NUL character.
*/
int
ut_format(
const ut_unit* const unit,
char* buf,
size_t size,
unsigned opts);
/*
* Accepts a visitor to a unit.
*
* Arguments:
* unit Pointer to the unit to accept the visitor.
* visitor Pointer to the visitor of "unit".
* arg An arbitrary pointer that will be passed to "visitor".
* Returns:
* UT_BAD_ARG "unit" or "visitor" is NULL.
* UT_VISIT_ERROR A error occurred in "visitor" while visiting "unit".
* UT_SUCCESS Success.
*/
ut_status
ut_accept_visitor(
const ut_unit* const unit,
const ut_visitor* const visitor,
void* const arg);
/******************************************************************************
* Time Handling:
******************************************************************************/
/*
* Encodes a date as a double-precision value.
*
* Arguments:
* year The year.
* month The month.
* day The day (1 = the first of the month).
* Returns:
* The date encoded as a scalar value.
*/
double
ut_encode_date(
int year,
int month,
int day);
/*
* Encodes a time as a double-precision value.
*
* Arguments:
* hours The number of hours (0 = midnight).
* minutes The number of minutes.
* seconds The number of seconds.
* Returns:
* The clock-time encoded as a scalar value.
*/
double
ut_encode_clock(
int hours,
int minutes,
double seconds);
/*
* Encodes a time as a double-precision value. The convenience function is
* equivalent to "ut_encode_date(year,month,day) +
* ut_encode_clock(hour,minute,second)"
*
* Arguments:
* year The year.
* month The month.
* day The day.
* hour The hour.
* minute The minute.
* second The second.
* Returns:
* The time encoded as a scalar value.
*/
double
ut_encode_time(
const int year,
const int month,
const int day,
const int hour,
const int minute,
const double second);
/*
* Decodes a time from a double-precision value.
*
* Arguments:
* value The value to be decoded.
* year Pointer to the variable to be set to the year.
* month Pointer to the variable to be set to the month.
* day Pointer to the variable to be set to the day.
* hour Pointer to the variable to be set to the hour.
* minute Pointer to the variable to be set to the minute.
* second Pointer to the variable to be set to the second.
* resolution Pointer to the variable to be set to the resolution
* of the decoded time in seconds.
*/
void
ut_decode_time(
double value,
int *year,
int *month,
int *day,
int *hour,
int *minute,
double *second,
double *resolution);
/******************************************************************************
* Error Handling:
******************************************************************************/
/*
* Returns the status of the last operation by the units module. This function
* will not change the status.
*/
ut_status
ut_get_status(void);
/*
* Sets the status of the units module. This function would not normally be
* called by the user unless they were doing their own parsing or formatting.
*
* Arguments:
* status The status of the units module.
*/
void
ut_set_status(
ut_status status);
/*
* Handles an error-message.
*
* Arguments:
* fmt The format for the error-message.
* ... The arguments for "fmt".
* Returns:
* <0 An output error was encountered.
* else The number of bytes of "fmt" and "arg" written excluding any
* terminating NUL.
*/
int
ut_handle_error_message(
const char* const fmt,
...);
/*
* Returns the previously-installed error-message handler and optionally
* installs a new handler. The initial handler is "ut_write_to_stderr()".
*
* Arguments:
* handler NULL or pointer to the error-message handler. If NULL,
* then the handler is not changed. The
* currently-installed handler can be obtained this way.
* Returns:
* Pointer to the previously-installed error-message handler.
*/
ut_error_message_handler
ut_set_error_message_handler(
ut_error_message_handler handler);
/*
* Writes an error-message to the standard-error stream when received and
* appends a newline. This is the initial error-message handler.
*
* Arguments:
* fmt The format for the error-message.
* args The arguments of "fmt".
* Returns:
* <0 A output error was encountered. See "errno".
* else The number of bytes of "fmt" and "arg" written excluding any
* terminating NUL.
*/
int
ut_write_to_stderr(
const char* const fmt,
va_list args);
/*
* Does nothing with an error-message.
*
* Arguments:
* fmt The format for the error-message.
* args The arguments of "fmt".
* Returns:
* 0 Always.
*/
int
ut_ignore(
const char* const fmt,
va_list args);
#ifdef __cplusplus
}
#endif
#endif
|