/usr/include/rec.h is in librec-dev 1.7-1.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 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 | /* -*- mode: C -*-
*
* File: rec.h
* Date: Fri Feb 27 20:04:59 2009
*
* GNU recutils - Main Header
*
*/
/* Copyright (C) 2009-2014 Jose E. Marchesi */
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GNU_REC_H
#define GNU_REC_H
#include <stdbool.h>
#include <stdio.h>
#include <fcntl.h>
/*
* rec format version implemented by this library.
*/
#define REC_VERSION_MAJOR 1
#define REC_VERSION_MINOR 0
#define REC_VERSION_STRING "1.0"
/*
* INITIALIZATION of the library
*/
void rec_init (void);
void rec_fini (void);
/*
* HETEROGENEOUS ORDERED SETS (MULTI-SETS)
*
* Element types: A, B, C
*
* type value next_A next_B next_C
* +-----+----------+-------+--------+--------+
* | | | | | |
* +-----+----------+-------+--------+--------+
* . . . . . .
* | | | | | |
* +-----+----------+-------+--------+--------+
*/
/* Opaque data type representing a multi-set. */
typedef struct rec_mset_s *rec_mset_t;
/* Opaque data type representing an element which is stored in the
multi-set. */
typedef struct rec_mset_elem_s *rec_mset_elem_t;
/* Structure to hold iterators in the stack. Note that the inner
structure must have the same structure than the gl_list_iterator_t
structure in the internal (and not distributed) gl_list.h. This
structure must be keep up to date. */
typedef struct
{
void *vtable;
void *list;
size_t count;
void *p; void *q;
size_t i; size_t j;
} rec_mset_list_iter_t;
typedef struct
{
rec_mset_t mset;
rec_mset_list_iter_t list_iter;
} rec_mset_iterator_t;
/* Data types for the callbacks that can be registered in the
multi-set and will be triggered to some events. */
typedef void (*rec_mset_disp_fn_t) (void *data);
typedef bool (*rec_mset_equal_fn_t) (void *data1, void *data2);
typedef void *(*rec_mset_dup_fn_t) (void *data);
typedef int (*rec_mset_compare_fn_t) (void *data1, void *data2, int type2);
/* Data type representing an element type in a multi-set. This type
is assured to be a scalar and thus it is possible to use the
comparison operators, but otherwise its contents must be
opaque. */
typedef int rec_mset_type_t;
#define MSET_ANY 0
/*************** Creating and destroying multi-sets *****************/
/* Create a new empty multi-set and return a reference to it. NULL is
returned if there is no enough memory to complete the
operation. */
rec_mset_t rec_mset_new (void);
/* Destroy a multi-set, freeing all used resources. This disposes all
the memory used by the mset internals, but not the data elements
stored in the multi-set. */
void rec_mset_destroy (rec_mset_t mset);
/* Create a copy of a multi-set and return a reference to it. This
operation performs a deep copy using the user-provided callback to
duplicate the elements stored in the set. NULL is returned if
there is no enough memory to complete the operation. */
rec_mset_t rec_mset_dup (rec_mset_t mset);
/*************** Registering Types in a multi-set *****************/
/* Return true if the multi-set has the specified TYPE registered.
Return false otherwise. Note that this function always returns
true when TYPE is MSET_ANY. */
bool rec_mset_type_p (rec_mset_t mset, rec_mset_type_t type);
/* Register a type in a multi-set. NAME must be a NULL-terminated
string with a unique name that will identify the type. The
provided callbacks will be called when needed. This function
returns an integer value that will identify the newly created type.
The only assumption user code can make about this number is that it
cant equal MSET_ANY. */
rec_mset_type_t rec_mset_register_type (rec_mset_t mset,
char *name,
rec_mset_disp_fn_t disp_fn,
rec_mset_equal_fn_t equal_fn,
rec_mset_dup_fn_t dup_fn,
rec_mset_compare_fn_t compare_fn);
/* Return the number of elements of the given type stored in a
multi-set. If TYPE is MSET_ANY then the total number of elements
stored in the set is returned, regardless their type. If the
specified type does not exist in the multi-set then this function
returns 0. */
size_t rec_mset_count (rec_mset_t mset, rec_mset_type_t type);
/*************** Getting, inserting and removing elements **********/
/* Get the data stored at a specific position in a mset. The returned
data occupies the POSITIONth position in the internal list of
elements of the specified type. If there is no element stored at
POSITION this function returns NULL. */
void *rec_mset_get_at (rec_mset_t mset,
rec_mset_type_t type,
size_t position);
/* Create a new element at a specific position in a mset, storing a
given data. If POSITION is 0 then the element is prepended. If
POSITION is equal or bigger than the number of the existing
elements with the same type in the mset then the new element is
appended. The function returns the newly created element, or NULL
if there is not enough memory to perform the operation. */
rec_mset_elem_t rec_mset_insert_at (rec_mset_t mset,
rec_mset_type_t type,
void *data,
size_t position);
/* Insert some given data just after another element in a mset. The
function returns the newly created element, or NULL if there was no
enough memory to perform the operation. */
rec_mset_elem_t rec_mset_insert_after (rec_mset_t mset,
rec_mset_type_t type,
void *data,
rec_mset_elem_t elem);
/* Append some given daata to a mset. This is equivalent to call
rec_mset_insert_at specifying a position equal or bigger than the
number of the existing elements with type TYPE in the mset. The
function returns the newly created element, or NULL if there was no
enough memory to perform the operation. */
rec_mset_elem_t rec_mset_append (rec_mset_t mset,
rec_mset_type_t elem_type,
void *data,
rec_mset_type_t type);
/* Add some given data to a mset. The position where the new element
is inserted depends on the sorting criteria implemented by the
compare_fn callback for the element type. The function returns the
newly created element, or NULL if there was no enough memory to
perform the operation. */
rec_mset_elem_t rec_mset_add_sorted (rec_mset_t mset,
rec_mset_type_t type,
void *data);
/* Remove the element occupying the specified position from a record
set. This function returns true if the element was removed, and
false if there were no element stored at the specified
position. */
bool rec_mset_remove_at (rec_mset_t mset,
rec_mset_type_t type,
size_t position);
/* Remove an element from the multi-set. The function returns true if
the element was found in the list and removed. */
bool rec_mset_remove_elem (rec_mset_t mset, rec_mset_elem_t elem);
/* Search for an element storing the specified data in a mset and
return it. NULL is returned in case no element in the record set
is storing DATA. */
rec_mset_elem_t rec_mset_search (rec_mset_t mset, void *data);
/*************** Iterating on mset elements *************************/
/* Create and return an iterator traversing elements in the multi-set.
The mset contents must not be modified while the iterator is in
use, except for replacing or removing the last returned
element. */
rec_mset_iterator_t rec_mset_iterator (rec_mset_t mset);
/* Advance the iterator to the next element of the given type. The
data stored by the next element is stored in *DATA if DATA is
non-NULL and a reference to the element in *ELEM if ELEM is
non-NULL. The function returns true if there is a next element to
which iterate to, and false otherwise. */
bool rec_mset_iterator_next (rec_mset_iterator_t *iterator,
rec_mset_type_t type,
const void **data,
rec_mset_elem_t *elem);
/* Free an iterator. */
void rec_mset_iterator_free (rec_mset_iterator_t *iterator);
/*************** Managing mset elements ******************************/
/* Return the type of the given multi-set element. Since every
element must be of some concrete type, the returned value cannot be
equal to MSET_ANY. */
rec_mset_type_t rec_mset_elem_type (rec_mset_elem_t elem);
/* Set the type of the given multi-set element. This function is
useful to transform records into comments. */
void rec_mset_elem_set_type (rec_mset_elem_t elem, rec_mset_type_t type);
/* Return a void pointer pointing to the data stored in the given mset
element. If no data was stored in the element then this function
returns NULL. */
void *rec_mset_elem_data (rec_mset_elem_t elem);
/* Set the data stored in a multi-set element. The memory pointed by
the previous value of the internal pointer is not freed or altered
in any other way by this operation. */
void rec_mset_elem_set_data (rec_mset_elem_t elem, void *data);
/* Determine whether the values stored in two multi-set elements are
equal. The comparison is performed using the user-provided
compare_fn callback. */
bool rec_mset_elem_equal_p (rec_mset_elem_t elem1, rec_mset_elem_t elem2);
/* Create a copy of the data stored in a mset element and return a
reference to it. This uses the user-provided callback to duplicate
the data. NULL is returned if there is no enough memory to
complete the operation. */
void *rec_mset_elem_dup_data (rec_mset_elem_t elem);
/************** Sorting, grouping and other operations **************/
/* Sort a given multi-set using the compare_fn callbacks provided by
the user when defining the types of the elements stored. This is a
destructive operation. Returns a copy of the mset argument if the
operation suceeded, NULL if there is not enough memory to perform
the operation. */
rec_mset_t rec_mset_sort (rec_mset_t mset);
/************************* Debugging ********************************/
/* Dump the contents of a multi-set to the terminal. For debugging
purposes. */
void rec_mset_dump (rec_mset_t mset);
/*
* FLEXIBLE BUFFERS
*
* A flexible buffer (rec_buf_t) is a buffer to which stream-like
* operations can be applied. Its size will grow as required.
*/
typedef struct rec_buf_s *rec_buf_t;
rec_buf_t rec_buf_new (char **data, size_t *size);
void rec_buf_close (rec_buf_t buffer);
/* rec_buf_putc returns the character written as an unsigned char cast
to an int, or EOF on error. */
int rec_buf_putc (int c, rec_buf_t buffer);
/* rec_buf_puts returns a non-negative number on success (number of
characters written), or EOF on error. */
int rec_buf_puts (const char *s, rec_buf_t buffer);
void rec_buf_rewind (rec_buf_t buf, int n);
/*
* COMMENTS
*
* A comment is a block of text. The printed representation of a
* comment includes a sharp (#) character after each newline (\n)
* character.
*/
typedef char *rec_comment_t;
/* Create a new comment and return it. NULL is returned if there is
not enough memory to perform the operation. */
rec_comment_t rec_comment_new (char *text);
/* Destroy a comment, freeing all used resources. */
void rec_comment_destroy (rec_comment_t comment);
/* Make a copy of the passed comment and return it. NULL is returned
if there is not enough memory to perform the operation. */
rec_comment_t rec_comment_dup (rec_comment_t comment);
/* Return a string containing the text in the comment. */
char *rec_comment_text (rec_comment_t comment);
/* Set the text of a comment. Any previous text associated with the
comment is destroyed and its memory freed. */
void rec_comment_set_text (rec_comment_t *comment, char *text);
/* Determine whether the texts stored in two given comments are
equal. */
bool rec_comment_equal_p (rec_comment_t comment1, rec_comment_t comment2);
/* FIELD NAMES
*
*/
/******************* Regexps for field names *******************/
#define REC_FNAME_RE "[a-zA-Z%][a-zA-Z0-9_]*"
#define REC_TYPE_NAME_RE "[a-zA-Z][a-zA-Z0-9_-]*"
#define REC_URL_REGEXP "(file|http|ftp|https)://[^ \t]+"
#define REC_FILE_REGEXP "(/?[^/ \t\n]+)+"
/******************* Field data types **************************/
/*
* The following enumeration contains identifiers for the standard
* fields used by the library.
*
* Changes to this enumerated value will require some fixes in
* rec-field-name.c.
*/
enum rec_std_field_e
{
REC_FIELD_AUTO = 0,
REC_FIELD_CONFIDENTIAL,
REC_FIELD_KEY,
REC_FIELD_MANDATORY,
REC_FIELD_PROHIBIT,
REC_FIELD_REC,
REC_FIELD_SIZE,
REC_FIELD_SORT,
REC_FIELD_TYPE,
REC_FIELD_TYPEDEF,
REC_FIELD_UNIQUE,
REC_FIELD_CONSTRAINT,
REC_FIELD_ALLOWED
};
/******************* Field name utilities **********************/
/* Determine whether two given strings contain the same field name.
Note that this function does not check wheter the strings actually
contain valid field names. */
bool rec_field_name_equal_p (const char *name1, const char *name2);
/* Determine whether a given string is a correct field name. */
bool rec_field_name_p (const char *str);
/* Normalise a field name. Any non alphanumeric character, including
'_', '-' and '%', are transformed into '_'. This function returns
NULL if there is not enough memory to perform the operation. */
char *rec_field_name_normalise (const char *str);
/* Return the field name corresponding to a standard field, as defined
above. */
const char *rec_std_field_name (enum rec_std_field_e std_field);
/*
* FIELD EXPRESSIONS
*
* A Field expression is composed by a sequence of "elements". Each
* element makes a reference to one or more fields in a record.
*/
/* Opaque data types for field expressions and the elements stored in
them. */
typedef struct rec_fex_s *rec_fex_t;
typedef struct rec_fex_elem_s *rec_fex_elem_t;
enum rec_fex_kind_e
{
REC_FEX_SIMPLE,
REC_FEX_CSV,
REC_FEX_SUBSCRIPTS
};
/* Regular expressions matching written fexes. */
#define REC_FNAME_FEX_RE REC_FNAME_RE "(\\." REC_FNAME_RE ")?"
#define REC_FNAME_LIST_RE REC_FNAME_RE "([ \n\t]+" REC_FNAME_RE ")*"
#define REC_FNAME_LIST_CS_RE REC_FNAME_FEX_RE "(," REC_FNAME_FEX_RE ")*"
#define REC_FNAME_SUB_RE REC_FNAME_FEX_RE "(\\[[0-9]+(-[0-9]+)?\\])?"
#define REC_FEX_FUNCTION_NAME "[a-zA-Z_][a-zA-Z0-9_]*"
#define REC_FEX_CALL REC_FEX_FUNCTION_NAME "\\(" REC_FNAME_FEX_RE "\\)"
#define REC_FNAME_LIST_SUB_ELEM_RE "(" REC_FNAME_SUB_RE "|" REC_FEX_CALL ")" "(:" REC_FNAME_FEX_RE ")?"
#define REC_FNAME_LIST_SUB_RE REC_FNAME_LIST_SUB_ELEM_RE "(," REC_FNAME_LIST_SUB_ELEM_RE ")*"
/*********** Creating and destroying field expressions ************/
/* Parse and create a field expression, and return it. A fex kind
shall be specified in KIND. If STR does not contain a valid FEX of
the given kind then NULL is returned. If there is not enough
memory to perform the operation then NULL is returned. If STR is
NULL then an empty fex is returned. */
rec_fex_t rec_fex_new (const char *str, enum rec_fex_kind_e kind);
/* Destroy a field expression, freeing any used resource. */
void rec_fex_destroy (rec_fex_t fex);
/* Create a copy of a given fex and return a reference to it. If
there is not enough memory to perform the operation then NULL is
returned. */
rec_fex_t rec_fex_dup (rec_fex_t fex);
/********* Getting and setting field expression properties **********/
/* Get the number of elements stored in a field expression. */
size_t rec_fex_size (rec_fex_t fex);
/* Check whether a given field (or set of fields) identified by their
name and indexes, are contained in a fex. */
bool rec_fex_member_p (rec_fex_t fex, const char *fname, int min, int max);
/* Get the element of a field expression occupying the given position.
If the position is invalid then NULL is returned. */
rec_fex_elem_t rec_fex_get (rec_fex_t fex, size_t position);
/* Append an element at the end of the fex and return it. This
function returns NULL if there is not enough memory to perform the
operation. */
rec_fex_elem_t rec_fex_append (rec_fex_t fex, const char *fname,
int min, int max);
/* Determine whether all the elements of the given FEX are function
calls. */
bool rec_fex_all_calls_p (rec_fex_t fex);
/**************** Accessing field expression elements **************/
/* Return the name of the field(s) referred by a given fex
element. */
const char *rec_fex_elem_field_name (rec_fex_elem_t elem);
/* Set the name of the field(s) referred by a given fex element. This
function returns 'false' if there is not enough memory to perform
the operation. */
bool rec_fex_elem_set_field_name (rec_fex_elem_t elem, const char *fname);
/* Get the 'min' index associated with the field(s) referred by a
given fex element. */
int rec_fex_elem_min (rec_fex_elem_t elem);
/* Get the 'max' index associated with the field(s) referred by a
given fex element. Note that if the index is unused (the element
refers to just one field) then -1 is returned. */
int rec_fex_elem_max (rec_fex_elem_t elem);
/* Get the 'rewrite_to' field name associated with the field(s) referred
by a given fex element. If no rewrite rule was specified in the
fex entry then NULL is returned. */
const char *rec_fex_elem_rewrite_to (rec_fex_elem_t elem);
/* Get the function name associated with a given fex element. If the
fex entry is not a function call then NULL is returned. */
const char *rec_fex_elem_function_name (rec_fex_elem_t elem);
/* Get the pointer to the context data to be used in the function
call, if any. */
void **rec_fex_elem_function_data (rec_fex_elem_t elem);
/*********** Miscellaneous field expressions functions ************/
/* Check whether a given string STR contains a proper fex description
of type KIND. */
bool rec_fex_check (const char *str, enum rec_fex_kind_e kind);
/* Sort the elements of a fex using the 'min' index of the elements as
the sorting criteria. */
void rec_fex_sort (rec_fex_t fex);
/* Get the written form of a field expression. This function returns
NULL if there is not enough memory to perform the operation. */
char *rec_fex_str (rec_fex_t fex, enum rec_fex_kind_e kind);
/*
* FIELD TYPES
*
*/
enum rec_type_kind_e
{
/* Unrestricted. */
REC_TYPE_NONE = 0,
/* An integer number. */
REC_TYPE_INT,
/* A Boolean. */
REC_TYPE_BOOL,
/* An integer number within a given range. */
REC_TYPE_RANGE,
/* A real number. */
REC_TYPE_REAL,
/* A string with a limitation on its size. */
REC_TYPE_SIZE,
/* A line. */
REC_TYPE_LINE,
/* A regexp. */
REC_TYPE_REGEXP,
/* A date. */
REC_TYPE_DATE,
/* An Enumeration. */
REC_TYPE_ENUM,
/* A field name. */
REC_TYPE_FIELD,
/* An email. */
REC_TYPE_EMAIL,
/* An universally unique identifier (uuid). */
REC_TYPE_UUID,
/* A foreign key. */
REC_TYPE_REC
};
typedef struct rec_type_s *rec_type_t;
/* Create a new type based on the textual description in STR. */
rec_type_t rec_type_new (const char *str);
/* Destroy a type. */
void rec_type_destroy (rec_type_t type);
/* Determine whether a string contains a valid type description. */
bool rec_type_descr_p (const char *str);
/* Get the kind of the type. The _str version returns a string with
the name of the type. */
enum rec_type_kind_e rec_type_kind (rec_type_t type);
char *rec_type_kind_str (rec_type_t type);
/* Get the min and max parametes of a range type. If the type does
not define a range then -1 is returned. */
int rec_type_min (rec_type_t type);
int rec_type_max (rec_type_t type);
/* Get the record set name of a rec type. If the type does not define
a rec then NULL is returned. */
const char *rec_type_rec (rec_type_t type);
/* Get and set the name of a type. Types are created anonymous by
rec_type_new, so the getter will return NULL unless a name is
set. */
const char *rec_type_name (rec_type_t type);
void rec_type_set_name (rec_type_t type, const char *name);
/* Determine whether two types are the same type.
*
* Two types are equal if,
*
* - They are of the same kind, and
*
* - Depending on the kind of types:
*
* + For sizes
*
* The maximum size specified in both types is the same.
*
* + For ranges
*
* The ranges specified in both types are the same.
*
* + For enums
*
* Both enums have the same number of entries, they are identical
* and in the same order.
*
* + For regexps
*
* They are never equal.
*/
bool rec_type_equal_p (rec_type_t type1, rec_type_t type2);
/* Check the contents of a string against a type. In case some error
arises, return it in ERROR_STR if it is not NULL. */
bool rec_type_check (rec_type_t type, const char *str, char **error_str);
/* Compare two values of a given type. The comparison criteria will
vary depending of the given type: numerical for ints and reals,
time comparison for dates, etc. If TYPE is NULL then a
lexicographic comparison is performed. Return -1 if VAL1 < VAL2, 0
if VAL1 == VAL2 and 1 if VAL1 > VAL2. */
int rec_type_values_cmp (rec_type_t type, const char *val1, const char *val2);
/*
* TYPE REGISTRIES.
*
* Type registries are collections of named types. The following API
* provides facilities to maintain type registries.
*/
typedef struct rec_type_reg_s *rec_type_reg_t;
/* Create and return an empty type registry. NULL is returned if
there is not enough memory to perform the operation. */
rec_type_reg_t rec_type_reg_new (void);
/* Destroy a type registry, freeing resources. */
void rec_type_reg_destroy (rec_type_reg_t reg);
/* Insert a new type in the type registry. If a type with the same
name already exists in the registry then it gets replaced. */
void rec_type_reg_add (rec_type_reg_t reg, rec_type_t type);
/* Insert a new type in the type registry as a synonim of another
type. If a type with the same name already exists in the registry
then it gets replaced. */
void rec_type_reg_add_synonym (rec_type_reg_t reg, const char *type_name,
const char *to_name);
/* Get the type named TYPE_NAME stored in REG. If it does not exist
NULL is returned. */
rec_type_t rec_type_reg_get (rec_type_reg_t reg, const char *type_name);
/*
* FIELDS
*
* A field is an association between a label and a value.
*/
/* Opaque data type representing a field. */
typedef struct rec_field_s *rec_field_t;
/*************** Creating and destroying fields *****************/
/* Create a new field and return a reference to it. NULL is returned
if there is no enough memory to perform the operation. */
rec_field_t rec_field_new (const char *name, const char *value);
/* Destroy a field freeing all used resources. This disposes all the
memory used by the field internals. */
void rec_field_destroy (rec_field_t field);
/* Create a copy of a field and return a reference to it. This
operation performs a deep copy of the contents of the field. NULL
is returned if there is no enough memory to perform the
operation. */
rec_field_t rec_field_dup (rec_field_t field);
/******************** Comparing fields ****************************/
/* Determine wether two given fields are equal (i.e. they have equal
names but possibly different values). */
bool rec_field_equal_p (rec_field_t field1, rec_field_t field2);
/************ Getting and Setting field properties *****************/
/* Return a NULL terminated string containing the name of a field.
Note that this function can't return the empty string for a
properly initialized field. */
const char *rec_field_name (rec_field_t field);
/* Set the name of a field. This function returns 'false' if there is
not enough memory to perform the operation. */
bool rec_field_set_name (rec_field_t field, const char *name);
/* Return a NULL terminated string containing the value of a field,
i.e. the string stored in the field. The returned string may be
empty if the field has no value, but never NULL. */
const char *rec_field_value (rec_field_t field);
/* Set the value of a given field to the given string. This function
returns 'false' if there is not enough memory to perform the
operation. */
bool rec_field_set_value (rec_field_t field, const char *value);
/* Return a string describing the source of the field. The specific
meaning of the source depends on the user: it may be a file name,
or something else. This function returns NULL for a field for
which a source was never set. */
const char *rec_field_source (rec_field_t field);
/* Set a string describing the source of the field. Any previous
string associated to the field is destroyed and the memory it
occupies is freed. This function returns 'false' if there is not
enough memory to perform the operation. */
bool rec_field_set_source (rec_field_t field, const char *source);
/* Return an integer representing the location of the field within its
source. The specific meaning of the location depends on the user:
it may be a line number, or something else. This function returns
0 for fields not having a defined source. */
size_t rec_field_location (rec_field_t field);
/* Return the textual representation for the location of a field
within its source. This function returns NULL for fields not
having a defined source. */
const char *rec_field_location_str (rec_field_t field);
/* Set a number as the new location for the given field. Any
previously stored location is forgotten. This function returns
'false' if there is not enough memory to perform the operation. */
bool rec_field_set_location (rec_field_t field, size_t location);
/* Return an integer representing the char location of the field
within its source. The specific meaning of the location depends on
the user, usually being the offset in bytes since the beginning of
a file or memory buffer. This function returns 0 for fields not
having a defined source. */
size_t rec_field_char_location (rec_field_t field);
/* Return the textual representation for the char location of a field
within its source. This function returns NULL for fields not
having a defined source. */
const char *rec_field_char_location_str (rec_field_t field);
/* Set a number as the new char location for the given field. Any
previously stored char location is forgotten. This function
returns 'false' if there is not enough memory to perform the
operation. */
bool rec_field_set_char_location (rec_field_t field, size_t location);
/* Get/set the mark of a given field, which is an integer associated
to the field ADT. */
void rec_field_set_mark (rec_field_t field, int mark);
int rec_field_mark (rec_field_t field);
/********************* Transformations in fields ********************/
/* Get the textual representation of a field and make it a comment
variable. This function returns NULL if there is no enough memory
to perform the operation. */
rec_comment_t rec_field_to_comment (rec_field_t field);
/*
* RECORDS
*
* A record is an ordered set of one or more fields intermixed with
* comment blocks.
*/
/* Opaque data type representing a record. */
typedef struct rec_record_s *rec_record_t;
/* Record mset types. Note that the following constants are relying
on the fact the multi-sets assign consecutive type ids starting
with 1. This is done this way for performance reasons, but it
means that this constants must be ajusted in case the order in
which the types are registered in rec_record_new changes. */
#define MSET_FIELD 1
#define MSET_COMMENT 2
/*************** Creating and destroying records *****************/
/* Create a new empty record and return a reference to it. NULL is
returned if there is no enough memory to perform the operation. */
rec_record_t rec_record_new (void);
/* Destroy a record, freeing all used resources. This disposes all
the memory used by the record internals, including any stored field
or comment. */
void rec_record_destroy (rec_record_t record);
/* Create a copy of a record and return a reference to it. This
operation performs a deep copy of the contained fields and
comments. NULL is returned if there is no enough memory to perform
the operation. */
rec_record_t rec_record_dup (rec_record_t record);
/******************** Comparing records ***************************/
/* Determine whether a given record is a subset of another record. A
record 'A' is a subset of a record 'B' if and only if for every
field or comment contained in 'A' there is an equivalent field or
comment in 'B'. The order of the elements is not relevant. */
bool rec_record_subset_p (rec_record_t record1, rec_record_t record2);
/* Determine whether a given record is equal to another record. A
record 'A' is equal to a record 'B' if the 'A' is a subset of 'B'
and 'B' is a subset of 'A'. */
bool rec_record_equal_p (rec_record_t record1, rec_record_t record2);
/************ Getting and Setting record properties ****************/
/* Return the multi-set containing the elements stored by the given
record. */
rec_mset_t rec_record_mset (rec_record_t record);
/* Return the number of elements stored in the given record, of any
type. */
size_t rec_record_num_elems (rec_record_t record);
/* Return the number of fields stored in the given record. */
size_t rec_record_num_fields (rec_record_t record);
/* Return the number of comments stored in the given record. */
size_t rec_record_num_comments (rec_record_t record);
/* Return a string describing the source of the record. The specific
meaning of the source depends on the user: it may be a file name,
or something else. This function returns NULL for a record for
which a source was never set. */
char *rec_record_source (rec_record_t record);
/* Set a string describing the source of the record. Any previous
string associated to the record is destroyed and the memory it
occupies is freed. */
void rec_record_set_source (rec_record_t record, char *source);
/* Return an integer representing the location of the record within
its source. The specific meaning of the location depends on the
user: it may be a line number, or something else. This function
returns 0 for records not having a defined source. */
size_t rec_record_location (rec_record_t record);
/* Return the textual representation for the location of a record
within its source. This function returns NULL for records not
having a defined source. */
char *rec_record_location_str (rec_record_t record);
/* Set a number as the new location for the given record. Any
previously stored location is forgotten. */
void rec_record_set_location (rec_record_t record, size_t location);
/* Return an integer representing the char location of the record
within its source. The specific meaning of the location depends on
the user, usually being the offset in bytes since the beginning of
a file or memory buffer. This function returns 0 for records not
having a defined source. */
size_t rec_record_char_location (rec_record_t record);
/* Return the textual representation for the char location of a record
within its source. This function returns NULL for records not
having a defined source. */
char *rec_record_char_location_str (rec_record_t record);
/* Set a number as the new char location for the given record. Any
previously stored char location is forgotten. */
void rec_record_set_char_location (rec_record_t record, size_t char_location);
/* Return the position occupied by the specified field in the
specified records, not considering comments. */
size_t rec_record_get_field_index (rec_record_t record, rec_field_t field);
/* Return the position occupied by the specified field in the
specified record among the fields having the same name. Thus, if
the provided field is the first having its name in the record then
the function returns 0. If it is the third then the function
returns 2. */
size_t rec_record_get_field_index_by_name (rec_record_t record, rec_field_t field);
/* Determine whether a record contains some field whose value is STR.
The string comparison can be either case-sensitive or
case-insensitive. */
bool rec_record_contains_value (rec_record_t record, const char *value, bool case_insensitive);
/* Determine whether a record contains a field whose name is
FIELD_NAME and value FIELD_VALUE. */
bool rec_record_contains_field (rec_record_t record, const char *field_name, const char *field_value);
/* Determine whether a given record contains a field named after a
given field name. */
bool rec_record_field_p (rec_record_t record, const char *field_name);
/* Return the number of fields name after a given field name stored in
a record. */
size_t rec_record_get_num_fields_by_name (rec_record_t record,
const char *field_name);
/* Return the Nth field named after the given field name in a record.
This function returns NULL if there is no such a field. */
rec_field_t rec_record_get_field_by_name (rec_record_t record,
const char *field_name,
size_t n);
/* Remove the Nth field named after the given field name in a
record. */
void rec_record_remove_field_by_name (rec_record_t record,
const char *field_name,
size_t n);
/* Return the 'container pointer' of a record. It is a pointer which
is used by the user of the record. This function returns NULL if
no container pointer has been set in the record. */
void *rec_record_container (rec_record_t record);
/* Set the 'container pointer' of a record, replacing any previous
value. */
void rec_record_set_container (rec_record_t record, void *container);
/********************* Transformations in records *******************/
/* Get the textual representation of a record and make it a comment
variable. This function returns NULL if there is no enough memory
to perform the operation. */
rec_comment_t rec_record_to_comment (rec_record_t record);
/* Remove duplicated fields in a given record. Fields are compared by
field name and value. */
void rec_record_uniq (rec_record_t record);
/* Append two records. This function adds all the fields in
SRC_RECORD to DEST_RECORD. */
void rec_record_append (rec_record_t dest_record, rec_record_t src_record);
/********************* Field Marks in records **********************/
/* Reset the marks of all fields in a given records, setting all the
marks to 0. */
void rec_record_reset_marks (rec_record_t record);
/* Set the mark of a given field. Return true if the field is marked
as desired. Return false if the field is not stored in the
record. */
bool rec_record_mark_field (rec_record_t record, rec_field_t field, int mark);
/* Get the mark associated to a field in a record. If the given field
is not found in the record then return 0. */
int rec_record_field_mark (rec_record_t record, rec_field_t field);
/*
* RECORD SETS
*
* A record set is an ordered set of zero or more records and comments
* maybe preceded by a record descriptor.
*/
#define REC_RECORD_TYPE_RE REC_FNAME_RE
/* Opaque data type representing a record set. */
typedef struct rec_rset_s *rec_rset_t;
/* Opaque data type representing a selection expression. This is
placed here as a forward declaration. See below in this file for
the definition of the selection expressions stuff. */
typedef struct rec_sex_s *rec_sex_t;
/* Record set mset types. MSET_COMMENT is defined above. */
#define MSET_RECORD 1
/************ Creating and destroying record sets **************/
/* Create a new empty record set and return a reference to it. NULL
is returned if there is no enough memory to perform the
operation. */
rec_rset_t rec_rset_new (void);
/* Destroy a record set, freeing all user resources. This disposes
all the memory used by the record internals, including any stored
record or comment. */
void rec_rset_destroy (rec_rset_t rset);
/* Create a copy of a record set and return a reference to it. This
operation performs a deep copy of the contained records and
comments. NULL is returned if there is no enough memory to perform
the operation. */
rec_rset_t rec_rset_dup (rec_rset_t rset);
/********* Getting and Setting record set properties *************/
/* Return the multi-set containing the elements stored by the given
record set. */
rec_mset_t rec_rset_mset (rec_rset_t rset);
/* Return the number of elements stored in the given record set, of
any type. */
size_t rec_rset_num_elems (rec_rset_t rset);
/* Return the number of records stored in the given record set. */
size_t rec_rset_num_records (rec_rset_t rset);
/* Return the number of comments stored in the given record set. */
size_t rec_rset_num_comments (rec_rset_t rset);
/***************** Record descriptor management ******************/
/* Return the record descriptor of a given record set. NULL is
returned if the record set does not feature a record
descriptor. */
rec_record_t rec_rset_descriptor (rec_rset_t rset);
/* Set a new record descriptor for a given record set. If there was
previously a record descriptor in the rset then it is destroyed.
This function performs all the requires updates to the semantics
associated with record sets, such as the type registry, size
constraints, etc. If RECORD is NULL then the record set wont
feature a record descriptor. */
void rec_rset_set_descriptor (rec_rset_t rset, rec_record_t record);
/* Return the relative position of the descriptor with respect the
first element in the record set. For example, if there are two
comments before the record descriptor in the record set then this
function returns 3. */
size_t rec_rset_descriptor_pos (rec_rset_t rset);
/* Set the relative position of the descriptor with respect the first
element in the record set. See the documentation for
rec_rset_descriptor_pos for details. */
void rec_rset_set_descriptor_pos (rec_rset_t rset, size_t position);
/* Return the URL associated with a record set (external descriptor).
NULL is returned if the record set does not feature a record
descriptor, or if the record set is not featuring an external
descriptor. */
char *rec_rset_url (rec_rset_t rset);
/* Return the type name of a record set. NULL is returned if the
record set does not feature a record descriptor. */
char *rec_rset_type (rec_rset_t rset);
/* Set the type name of a record set. If there was not a record
descriptor in the rset then it is created with a single %rec field.
In case there was an existing descriptor in the rset then it is
updated to reflect the new name. */
void rec_rset_set_type (rec_rset_t rset, const char *type);
/************ Management of the type registry ***********************/
/* Return the type registry of a record set. Note that the registry
will be empty for a newly created rset. */
rec_type_reg_t rec_rset_get_type_reg (rec_rset_t rset);
/* Return the declared type for fields named after the provided field
name in a record set. NULL is returned if no such a type is
found. */
rec_type_t rec_rset_get_field_type (rec_rset_t rset,
const char *field_name);
/********************** Size constraints ****************************/
/* Return the minimum number of records allowed for a rset in its
record descriptor. This is 0 for record sets for which no size
constraints have been defined. */
size_t rec_rset_min_records (rec_rset_t rset);
/* Return the maximum number of records allowed for a rset in its
record descriptor. This is SIZE_MAX for record sets for which no
size constraints have been defined. */
size_t rec_rset_max_records (rec_rset_t rset);
/********************** Sex constraints *****************************/
/* Return the number of sex constraints defined in a record set. This
is 0 for record sets for which no sex constraints have been
defined. */
size_t rec_rset_num_sex_constraints (rec_rset_t rset);
/* Return a given sex constraint defined in a record sex. The
provided index must be between 0 and the value returned by
rec_rset_num_sex_constraints - 1. */
rec_sex_t rec_rset_sex_constraint (rec_rset_t rset, size_t index);
/********************** Other functionality *************************/
/* Rename a field in a record descriptor. Field names are not
modified in the records themselves, but only in the record
descriptor. Note that the comparisons of the field names are
EQL. */
void rec_rset_rename_field (rec_rset_t rset,
const char *field_name,
const char *new_field_name);
/* Return a fex with the names of all the fields defined as
auto-incremented fields in a record set. */
rec_fex_t rec_rset_auto (rec_rset_t rset);
/* Return the name of the key field of the record set. If the record
set does not have a key defined then return NULL. */
const char *rec_rset_key (rec_rset_t rset);
/* Return a fex with the names of all the fields defined as
confidential fields in a record set. */
rec_fex_t rec_rset_confidential (rec_rset_t rset);
/* Determine whether a given field name corresponds to a confidential
field in a record set. */
bool rec_rset_field_confidential_p (rec_rset_t rset, const char *field_name);
/* Return a string describing the source of the record set. The
specific meaning of the source depends on the user: it may be a
file name, or something else. This function returns NULL for a
record set for which a source was never set. */
char *rec_rset_source (rec_rset_t rset);
/* Set an orderd set of of field names that will be used as the
sorting criteria for a record set. The field names will take
precedence to any other way to define the sorting criteria, such as
the %sort special field in the record descriptor. This function
returns 'false' if there is not enough memory to perform the
operation. */
bool rec_rset_set_order_by_fields (rec_rset_t rset, rec_fex_t field_names);
/* Return the field names that are used to sort a record set. */
rec_fex_t rec_rset_order_by_fields (rec_rset_t rset);
/* Sort a record set. The SORT_BY parameter is a fex that, if non
NULL, contains the field names which will be used as the sorting
criteria. If no SORT_BY fields is specified then whatever sorting
criteria specified in the record set is used. If no sorting
criteria exists then the function is a no-op. The function returns
a copy of RSET or NULL if there is not enough memory to perform the
operation. */
rec_rset_t rec_rset_sort (rec_rset_t rset, rec_fex_t sort_by);
/* Group the records of a record set by the given fields in GROUP_BY.
The given record set must be sorted by GROUP_BY. Note that this
function uses the first field with the given names found in a
record, ignoring any subsequent field. It is up to the user to
provide the right records in order to get the desired results. The
function returns a copy of RSET or NULL if there was not enough
memory to perform the operation. */
rec_rset_t rec_rset_group (rec_rset_t rset, rec_fex_t group_by);
/* Add missing auto fields defined in a record set to a given record.
The record could not be stored in the record set used to determine
which auto fields to add. This function is a no-operation if the
given record set is not defining any auto field, or if the passed
record already contains all fields marked as auto in the record
set. The function returns a copy of RSET or NULL if there was not
enough memory to perform the operation. */
rec_rset_t rec_rset_add_auto_fields (rec_rset_t rset, rec_record_t record);
/*
* DATABASES
*
* A database is an ordered set of zero or more record sets.
*/
/* Opaque type representing a database. */
typedef struct rec_db_s *rec_db_t;
/* Opaque data type representing a registry of aggregates. This is
placed here as a forward declaration. See below in this file for
the description of field functions. */
typedef struct rec_aggregate_reg_s *rec_aggregate_reg_t;
/************ Creating and destrying databases *********************/
/* Create a new empty database and return it. This function returns
NULL if there is not enough memory to perform the operation. */
rec_db_t rec_db_new (void);
/* Destroy a database, freeing any used memory. This means that all
the record sets contained in the database are also destroyed. */
void rec_db_destroy (rec_db_t db);
/*********** Getting and setting properties of databases **********/
/* Return the number of record sets contained in a given record
set. */
size_t rec_db_size (rec_db_t db);
/*********** Managing record sets in a database *******************/
/* Return the record set occupying the given position in the database.
If no such record set is contained in the database then NULL is
returned. */
rec_rset_t rec_db_get_rset (rec_db_t db, size_t position);
/* Insert the given record set into the given database at the given
position. If POSITION >= rec_rset_size (DB), RSET is appended to
the list of fields. If POSITION < 0, RSET is prepended. Otherwise
RSET is inserted at the specified position. If the rset is inserted
then 'true' is returned. If there is an error then 'false' is
returned. */
bool rec_db_insert_rset (rec_db_t db, rec_rset_t rset, size_t position);
/* Remove the record set contained in the given position into the
given database. If POSITION >= rec_db_size (DB), the last record
set is deleted. If POSITION <= 0, the first record set is deleted.
Otherwise the record set occupying the specified position is
deleted. If a record set has been removed then 'true' is returned.
If there is an error or the database has no record sets 'false' is
returned. */
bool rec_db_remove_rset (rec_db_t db, size_t position);
/* Determine whether an rset named TYPE exists in a database. If TYPE
is NULL then it refers to the default record set. */
bool rec_db_type_p (rec_db_t db, const char *type);
/* Get the rset with the given type from db. This function returns
NULL if there is no a record set having that type. */
rec_rset_t rec_db_get_rset_by_type (rec_db_t db, const char *type);
/******************** Miscellaneous database functions ****************/
/* Return the registry of aggregates of the given database. */
rec_aggregate_reg_t rec_db_aggregates (rec_db_t db);
/******************** Database High-Level functions *******************/
/* Query for some data in a database. The resulting data is returned
in a record set.
This function takes the following arguments:
DB
Database to query.
TYPE
The type of records to query. This string must identify a
record set contained in the database. If TYPE is NULL then the
default record set, if any, is queried.
JOIN
If not NULL, this argument must be a string denoting a field
name. This field name must be a foreign key (field of type
'rec') defined in the selected record set. The query operation
will do an inner join using T1.Field = T2.Field as join
criteria.
INDEX
If not NULL, this argument is a pointer to a buffer containing
pairs of Min,Max indexes, identifying intervals of valid
records. The list of ends with the pair
REC_Q_NOINDEX,REC_Q_NOINDEX.
INDEX is mutually exclusive with any other selection option.
SEX
Selection expression which is evaluated for every record in the
referred record set. If SEX is NULL then all records are
selected.
This argument is mutually exclusive with any other selection
option.
FAST_STRING
If this argument is not NULL then it is a string which is used
as a fixed pattern. Records featuring fields containing
FAST_STRING as a substring in their values are selected.
This argument is mutually exclusive with any other selection
option.
RANDOM
If not 0, this argument indicates the number of random records
to select from the referred record set.
This argument is mutually exclusive with any other selection
option.
FEX
Field expression to apply to the matching records to build the
records in the result record set. If FEX is NULL then the
matching records are unaltered.
PASSWORD
Password to use to decrypt confidential fields. If the password
does not work then the encrypted fields are returned as-is. If
PASSWORD is NULL, or if it is the empty string, then no attempt
to decrypt encrypted fields will be performed.
GROUP_BY
If not NULL, group the record set by the given field names.
SORT_BY
If not NULL, sort the record set by the given field names.
FLAGS
ORed value of any of the following flags:
REC_Q_DESCRIPTOR
If set returned record set will feature a record descriptor. If
the query is involving a single record set then the descriptor
will be a copy of the descriptor of the referred record set, and
will feature the same record type name. Otherwise it will be
built from the several descriptors of the involved record sets,
and the record type name will be formed concatenating the type
names of the involved record sets. If this flag is not
activated then the returned record set won't feature a record
descriptor.
REC_Q_ICASE
If set the string operations in the selection expression will be
case-insensitive. If FALSE any string operation will be
case-sensitive.
This function returns NULL if there is not enough memory to
perform the operation. */
#define REC_F_DESCRIPTOR 1
#define REC_F_ICASE 2
#define REC_F_UNIQ 4
#define REC_Q_NOINDEX ((size_t)-1)
rec_rset_t rec_db_query (rec_db_t db,
const char *type,
const char *join,
size_t *index,
rec_sex_t sex,
const char *fast_string,
size_t random,
rec_fex_t fex,
const char *password,
rec_fex_t group_by,
rec_fex_t sort_by,
int flags);
/* Insert a new record into a database, either appending it to some
record set or replacing one or more existing records.
This function takes the following arguments:
DB
Database where to insert the record.
TYPE
Type of the new record. If there is an existing record set
holding records of that type then the record is added to it.
Otherwise a new record set is appended into the database.
INDEX
If not NULL, this argument is a pointer to a buffer containing
pairs of Min,Max indexes, identifying intervals of records that
will be replaced by copies of the provided record. The list of
ends with the pair REC_Q_NOINDEX,REC_Q_NOINDEX.
INDEX is mutually exclusive with any other selection option.
SEX
Selection expression which is evaluated for every record in the
referred record set. If SEX is NULL then all records are
selected.
This argument is mutually exclusive with any other selection
option.
FAST_STRING
If this argument is not NULL then it is a string which is used
as a fixed pattern. Records featuring fields containing
FAST_STRING as a substring in their values are selected.
This argument is mutually exclusive with any other selection
option.
RANDOM
If not 0, this argument indicates the number of random records
to select from the referred record set.
This argument is mutually exclusive with any other selection
option.
PASSWORD
Password to use to crypt confidential fields. If PASSWORD is
NULL, or if it is the empty string, then no attempt to crypt
confidential fields will be performed.
RECORD
Record to insert. If more than one record is replaced in the
database they will be substitued with copies of this record.
FLAGS
ORed value of any of the following flags:
REC_F_ICASE
If set the string operations in the selection expression will be
case-insensitive. If FALSE any string operation will be
case-sensitive.
REC_F_NOAUTO
If set then no auto-fields will be added to the newly created
records in the database.
If no selection option is used then the new record is appended to
either an existing record set identified by TYPE or to a newly
created record set. If some selection option is used then the
matching existing records will be replaced.
This function returns 'false' if there is not enough memory to
perform the operation. */
#define REC_F_NOAUTO 8
bool rec_db_insert (rec_db_t db,
const char *type,
size_t *index,
rec_sex_t sex,
const char *fast_string,
size_t random,
const char *password,
rec_record_t record,
int flags);
/* Delete records from a database, either physically removing them or
commenting them out.
This function takes the following arguments:
DB
Database where to remove records.
TYPE
Type of the records to remove.
INDEX
If not NULL, this argument is a pointer to a buffer containing
pairs of Min,Max indexes, identifying intervals of records that
will be deleted or commented out. The list of ends with the pair
REC_Q_NOINDEX,REC_Q_NOINDEX.
INDEX is mutually exclusive with any other selection option.
SEX
Selection expression which is evaluated for every record in the
referred record set. If SEX is NULL then all records are
selected.
This argument is mutually exclusive with any other selection
option.
FAST_STRING
If this argument is not NULL then it is a string which is used
as a fixed pattern. Records featuring fields containing
FAST_STRING as a substring in their values are selected.
This argument is mutually exclusive with any other selection
option.
RANDOM
If not 0, this argument indicates the number of random records
to select for deletion in the referred record set.
This argument is mutually exclusive with any other selection
option.
FLAGS
ORed value of any of the following flags:
REC_F_ICASE
If set the string operations in the selection expression will be
case-insensitive. If FALSE any string operation will be
case-sensitive.
REC_F_COMMENT_OUT
If set the selected records will be commented out instead of physically
removed from the database.
This function returns 'false' if there is not enough memory to
perform the operation. */
#define REC_F_COMMENT_OUT 16
bool rec_db_delete (rec_db_t db,
const char *type,
size_t *index,
rec_sex_t sex,
const char *fast_string,
size_t random,
int flags);
/* Manipulate the fields of the selected records in a database: remove
them, set their values or rename them.
This function takes the following arguments:
DB
Database where to set fields.
TYPE
Type of the records to act in.
INDEX
If not NULL, this argument is a pointer to a buffer containing
pairs of Min,Max indexes, identifying intervals of records that
will be deleted or commented out. The list of ends with the pair
REC_Q_NOINDEX,REC_Q_NOINDEX.
INDEX is mutually exclusive with any other selection option.
SEX
Selection expression which is evaluated for every record in the
referred record set. If SEX is NULL then all records are
selected.
This argument is mutually exclusive with any other selection
option.
FAST_STRING
If this argument is not NULL then it is a string which is used
as a fixed pattern. Records featuring fields containing
FAST_STRING as a substring in their values are selected.
This argument is mutually exclusive with any other selection
option.
RANDOM
If not 0, this argument indicates the number of random records
to select for manipulation in the referred record set.
This argument is mutually exclusive with any other selection
option.
FEX
Field expression selecting the fields in the selected records
which will be modified.
ACTION
Action to perform to the selected fields. Valid values for this
argument are:
REC_SET_ACT_RENAME
Rename the matching fields to the string pointed by ACTION_ARG.
REC_SET_ACT_SET
Set the value of the matching fields to the string pointed by
ACTION_ARG.
REC_SET_ACT_ADD
Add new fields with the names specified in the fex to the
selected records. The new fields will have the string pointed
by ACTION_ARG as their value.
REC_SET_ACT_SETADD
Set the selected fields to the value pointed by ACTION_ARG. IF
the fields dont exist then create them with that value.
REC_SET_ACT_DELETE
Delete the selected fields. ACTION_ARG is ignored by this
action.
REC_SET_ACT_COMMENT
Comment out the selected fields. ACTION_ARG is ignored by this
action.
ACTION_ARG
Argument to the selected action. It is ok to pass NULL for
actions which dont require an argument.
FLAGS
ORed value of any of the following flags:
REC_F_ICASE
If set the string operations in the selection expression will be
case-insensitive. If FALSE any string operation will be
case-sensitive.
This function return s'false' if there is not enough memory to
perform the operation.
*/
#define REC_SET_ACT_NONE 0
#define REC_SET_ACT_RENAME 1
#define REC_SET_ACT_SET 2
#define REC_SET_ACT_ADD 3
#define REC_SET_ACT_SETADD 4
#define REC_SET_ACT_DELETE 5
#define REC_SET_ACT_COMMENT 6
bool rec_db_set (rec_db_t db,
const char *type,
size_t *index,
rec_sex_t sex,
const char *fast_string,
size_t random,
rec_fex_t fex,
int action,
const char *action_arg,
int flags);
/*
* INTEGRITY.
*
*/
/* Check the integrity of all the record sets stored in a given
database. This function returns the number of errors found.
Descriptive messages about the errors are appended to ERRORS. */
int rec_int_check_db (rec_db_t db,
bool check_descriptors_p,
bool remote_descriptors_p,
rec_buf_t errors);
/* Check the integrity of a given record set. This function returns
the number of errors found. Descriptive messages about the errors
are appended to ERRORS. */
int rec_int_check_rset (rec_db_t db,
rec_rset_t rset,
bool check_descriptor_p,
bool remote_descriptor_p,
rec_buf_t errors);
/* Check the integrity of a database provided ORIG_REC is replaced by
REC. This function returns the number of errors found.
Descriptive messages about the errors are appended to ERRORS. */
int rec_int_check_record (rec_db_t db,
rec_rset_t rset,
rec_record_t orig_rec,
rec_record_t rec,
rec_buf_t errors);
/* Check the type of a given field. This function returns the number
of errors found. Descriptive messages about the errors are
appended to ERRORS. */
bool rec_int_check_field_type (rec_db_t db,
rec_rset_t rset,
rec_field_t field,
rec_buf_t errors);
/*
* PARSER
*
* The rec parser provides functions to parse field, records and
* entire record sets from a file stream or a memory buffer.
*/
/* Opaque data type representing a parser. */
typedef struct rec_parser_s *rec_parser_t;
/**************** Creating and destroying parsers ******************/
/* Create a parser associated with a given file stream that will be
used as the source for the tokens. If not enough memory, return
NULL. */
rec_parser_t rec_parser_new (FILE *in, const char *source);
/* Create a parser associated with a given buffer that will be used as
the source for the tokens. The buffer is of specified size and
doesn't have to be null-terminated. If not enough memory, return
NULL. */
rec_parser_t rec_parser_new_mem (const char *buffer, size_t size, const char *source);
/* Create a parser associated with a given null-terminated buffer that
will be used as the source for the tokens. If not enough memory,
return NULL. */
rec_parser_t rec_parser_new_str (const char *buffer, const char *source);
/* Destroy a parser, freeing all used resources. Note that this call
is not closing the associated file stream or the associated memory
buffer. */
void rec_parser_destroy (rec_parser_t parser);
/*********************** Parsing routines **************************/
/* Parse a field name and return it in FNAME. This function returns
'false' and the value in FNAME is undefined if a parse error is
found. */
bool rec_parse_field_name (rec_parser_t parser, char **fname);
/* Parse a field name from a string and return it. This function
returns NULL if a parse error is found. */
char *rec_parse_field_name_str (const char *str);
/* Parse a field and return it in FIELD. This function returns
'false' and the value in FIELD is undefined if a parse error is
found. */
bool rec_parse_field (rec_parser_t parser, rec_field_t *field);
/* Parse a record and return it in RECORD. This function returns
'false' and the value in RECORD is undefined if a parse error is
found. */
bool rec_parse_record (rec_parser_t parser, rec_record_t *record);
/* Parse a record from a string and return it. This function builds
up an ephimeral parser internally in order to do the parsing. This
function returns NULL if a parse error is found. */
rec_record_t rec_parse_record_str (const char *str);
/* Parse a record set and return it in RSET. This function returns
'false' and the value in RSET is undefined if a parse error is
found. */
bool rec_parse_rset (rec_parser_t parser, rec_rset_t *rset);
/* Parse a database and return it in DB. This function returns
'false' and the value in DB is undefined if a parse error is
found. */
bool rec_parse_db (rec_parser_t parser, rec_db_t *db);
/************ Getting and Setting properties of parsers *************/
/* Determine whether a given parser is in an EOF (end of file)
state. */
bool rec_parser_eof (rec_parser_t parser);
/* Determine whether a given parser is in an error state. If the
parser is in an error state then rec_parser_perror can be used to
get a string describing the error. */
bool rec_parser_error (rec_parser_t parser);
/* Reset the error status and EOF of a parser. */
void rec_parser_reset (rec_parser_t parser);
/* Print a message with details on the last parser error. This
* function produces a message on the standard error output,
* describing the last error encountered while parsing. First, if FMT
* is not NULL, it is printed along with any remaining argument. Then
* a colon and a space are printed, and finally an error message
* describing what went wrong.
*/
void rec_parser_perror (rec_parser_t parser, const char *fmt, ...);
/* Change the position in file of the parser to a given offset from
the start of the input. The line number is only used to store it
in the parsed records. Return 'false' on error, e.g. when the
stream used is not seekable or when the position is outside the
buffer. */
bool rec_parser_seek (rec_parser_t parser, size_t line_number, size_t position);
/* Return the current position in the file of the parser or -1 on error. */
long rec_parser_tell (rec_parser_t parser);
/*
* WRITER
*
* The rec writer provides functions to generate the written form of
* rec objects such as fields and records.
*/
/* Opaque data type representing a rec writer. */
typedef struct rec_writer_s *rec_writer_t;
/* Enumerated value identifying the operation modes of the writers.
The operation mode defines what kind of output the writer will
generate. */
enum rec_writer_mode_e
{
REC_WRITER_NORMAL, /* Generate output in rec format. */
REC_WRITER_VALUES, /* Generate output in values format. */
REC_WRITER_VALUES_ROW, /* Generate output in row format. */
REC_WRITER_SEXP /* Generate output in sexps. */
};
typedef enum rec_writer_mode_e rec_writer_mode_t;
/**************** Creating and destroying writers ******************/
/* Create a writer associated with a given file stream. If not enough
memory, return NULL. */
rec_writer_t rec_writer_new (FILE *out);
/* Create a writer associated with a given string. If not enough
memory, return NULL. */
rec_writer_t rec_writer_new_str (char **str, size_t *str_size);
/* Destroy a writer, freeing any used resources. Note that this call
is not closing the associated file stream, nor free the associated
string. */
void rec_writer_destroy (rec_writer_t writer);
/************ Getting and setting writer properties ***************/
/* Set whether the writer must "collapse" the output records when
writing record sets. */
void rec_writer_set_collapse (rec_writer_t writer, bool value);
/* Set whether the writer must skip comments when outputting record
sets and records. */
void rec_writer_set_skip_comments (rec_writer_t writer, bool value);
/* Set the operation mode of the writer. See the enumerated type
defined above for a list of allowed modes. Note that the mode can
be changed at any time. */
void rec_writer_set_mode (rec_writer_t writer, enum rec_writer_mode_e mode);
/************** Getting the properties of a writer ****************/
/* Determine whether a given writer is in an EOF (end-of-file)
state. */
bool rec_writer_eof (rec_writer_t writer);
/********************** Writing routines **************************/
/* Write a string in the given writer. This function returns 'false'
if there was an EOF condition. */
bool rec_write_string (rec_writer_t writer, const char *str);
/* Write a comment in the given writer. This function returns 'false'
if there was an EOF condition. */
bool rec_write_comment (rec_writer_t writer, rec_comment_t comment);
/* Write a field name in the given writer. This function returns
'false' if there was an EOF condition. */
bool rec_write_field_name (rec_writer_t writer, const char *field_name);
/* Write a field in the given writer. If NAME is not NULL, use it
instead of the proper name of the field. This function returns
'false' if there was an EOF condition. */
bool rec_write_field (rec_writer_t writer, rec_field_t field);
/* Write a record in the given writer. This function returns 'false'
if there was an EOF condition. */
bool rec_write_record (rec_writer_t writer, rec_record_t record);
/* Write a record set to the given writer. This function returns
'false' if there was an EOF condition. */
bool rec_write_rset (rec_writer_t writer, rec_rset_t rset);
/* Write a database to the given writer. This function returns
'false' if there was an EOF condition. */
bool rec_write_db (rec_writer_t writer, rec_db_t db);
/* Create a string with the written representation of a field name and
return it. This function returns NULL if there is not enough
memory to perform the operation. */
char *rec_write_field_name_str (const char *field_name, rec_writer_mode_t mode);
/* Create a string with the written representation of a field and
return it. This function returns NULL if there is not enough
memory to perform the operation. */
char *rec_write_field_str (rec_field_t field, rec_writer_mode_t mode);
/* Create a string with the written representation of a comment and
return it. This function returns NULL if there is not enough
memory to perform the operation. */
char *rec_write_comment_str (rec_comment_t comment, rec_writer_mode_t mode);
/*
* SELECTION EXPRESSIONS
*
* A selection expression is an expression that can be applied to a
* record. The result of the evaluation is a boolean value indicating
* whether the record matches the expression.
*
* The abbreviated term to refer to a selection expression is 'a sex'.
* The plural form is 'sexes'.
*/
/* The opaque type rec_sex_t is defined above in this file as a
forward declaration. */
/**************** Creating and destroying sexes ******************/
/* Create a new selection expression and return it. If there is not
enough memory to create the sex, then return NULL. */
rec_sex_t rec_sex_new (bool case_insensitive);
/* Destroy a sex, freeing any used resources. */
void rec_sex_destroy (rec_sex_t sex);
/**************** Compiling and applying sexes ******************/
/* Compile a sex. Sexes must be compiled before being used. If there
is a parse error return false. */
bool rec_sex_compile (rec_sex_t sex, const char *expr);
/* Apply a sex expression to a record, setting STATUS in accordance:
'true' if the record matched the sex, 'false' otherwise. The
function returns the same value that is stored in STATUS. */
bool rec_sex_eval (rec_sex_t sex, rec_record_t record, bool *status);
/* Apply a sex expression and get the result as an allocated
string. */
char *rec_sex_eval_str (rec_sex_t sex, rec_record_t record);
/**************** Miscellaneous sexes functions ******************/
/* Print the abstract syntax tree of a compiled sex. This function is
intended to be used for debugging purposes. */
void rec_sex_print_ast (rec_sex_t sex);
/*
* ENCRYPTION
*
* The following routines encrypt and decrypt fields in rec data.
*
* If librec was built without encryption support, all of them will do
* nothing and return 'false' as if an error occurred.
*/
/* Prefix used in the encrypted and ASCII encoded field values, which
is used to recognize encrypted values. */
#define REC_ENCRYPTED_PREFIX "encrypted-"
/**************** Encryption routines *******************************/
/* Encrypt a given buffer and place the encrypted data in an allocated
output buffer. This function returns 'false' if there was an error
while performing the encryption, such as an incorrect password or
an out-of-memory condition. */
bool rec_encrypt (char *in, size_t in_size, const char *password,
char **out, size_t *out_size);
/* Encrypt and ASCII-encode the value of a field used the provided
password. The REC_ENCRYPTED_PREFIX is prepended to the result.
This function returns 'false' if there was an error while
performing the encryption, such as an incorrect password or an
out-of-memory condition. */
bool rec_encrypt_field (rec_field_t field, const char *password);
/* Encrypt and ASCII-encode the fields of a record marked as
"confidential" in a given record set, using the provided password.
The REC_ENCRYPTED_PREFIX is prepended to the result. This function
returns 'false' if there was an error while performing the
encryption, such as an incorrect password or an out-of-memory
condition. */
bool rec_encrypt_record (rec_rset_t rset, rec_record_t record,
const char *password);
/**************** Decryption routines *******************************/
/* Decrypt a given buffer and place the decrypted data in an allocated
output buffer. This function returns 'false' if there was an error
while performing the decryption, such as an incorrect password or
an out-of-memory condition. */
bool rec_decrypt (char *in, size_t in_size, const char *password,
char **out, size_t *out_size);
/* Decrypt the value of a field used the provided password. This
function returns 'false' if there was an error while perfoming the
decryption, such as an incorrect password or an out-of-memory
condition. Note that this function uses the REC_ENCRYPTED_PREFIX
in order to determine whether a field is already encrypted. */
bool rec_decrypt_field (rec_field_t field, const char *password);
/* Decrypt the encrypted fields of a record marked as "confidential"
in a given record set, using the provided password. This function
returns 'false' if there was an error while performing the
decryption, such as an incorrect password or an out-of-memory
condition. Note that this function uses the REC_ENCRYPTED_PREFIX
in order to determine whether a field is already encrypted. */
bool rec_decrypt_record (rec_rset_t rset, rec_record_t record,
const char *password);
/*
* AGGREGATES
*
* The following routines and data types provide support for
* "aggregate functions". Aggregate functions are applied to sets of
* fields and return a single value.
*/
/* Data type representing an aggregate function. Aggregate functions
get a record set, a record, a field name and subscripts which can
be -1. The field functions must return a string, which may be
empty. If an out-of-memory condition occurs then they return
NULL. */
typedef char *(*rec_aggregate_t) (rec_rset_t rset,
rec_record_t record,
const char *field_name);
/*
* AGGREGATES REGISTRIES
*
* The following data types and functions provide support for
* maintaining registries with collections of aggregate functions.
* The aggregate functions are identified by a constant string that
* must be unique in the registry.
*/
/* See the definition of rec_aggregate_reg_t above. */
/******** Creating and destroying function registries ************/
/* Create a new, empty aggregates registry. If there is not error to
perform the operation then NULL is returned. */
rec_aggregate_reg_t rec_aggregate_reg_new (void);
/* Destroy a functions registry, freeing any used resources. */
void rec_aggregate_reg_destroy (rec_aggregate_reg_t func_reg);
/********* Registering functions and fetching them ***************/
/* Register a field function into a functions register, associating it
with a given constant string. If a function associated with the
given string already exists in the registry then it is substitued
by the provided function. The function true if the operation was
successful, and false if there was not enough memory to perform the
operation. */
bool rec_aggregate_reg_add (rec_aggregate_reg_t func_reg, const char *name, rec_aggregate_t function);
/* Fetch a field function from a functions registry. If no function
associated with NAME is found in the registry then NULL is
returned. */
rec_aggregate_t rec_aggregate_reg_get (rec_aggregate_reg_t func_get, const char *name);
/* Register the standard built-in functions shipped with librec in the
given aggregate register. */
void rec_aggregate_reg_add_standard (rec_aggregate_reg_t func_reg);
/* Determine whether a given function name is a standard aggregate.
The comparison is case-insensitive. */
bool rec_aggregate_std_p (const char *name);
#endif /* !GNU_REC_H */
/* End of rec.h */
|