Use different capacities for root and child dict
[eleutheria.git] / proplib / prop_du.c
blobcb63ea6e2bfb229660b12b2b30064c0a4b2fe5b7
1 /*
2 * [root dictionary]
3 * [child dictionary]
4 * [path]
5 * [size]
6 * [type]
7 * [child dictionary]
8 * [path]
9 * [size]
10 * [type]
11 * ...
13 * Compile with:
14 * gcc prop_du.c -o prop_du -lprop -Wall -W -Wextra -ansi -pedantic
17 #include <err.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <prop/proplib.h>
23 #define INIT_ROOT_CAPACITY 100 /* root's dict initial capacity */
24 #define INIT_CHILD_CAPACITY 3 /* child's dict initial capacity */
25 #define MAX_STR 100
26 #define MAX_TOKENS 3
28 int main(void)
30 char str[MAX_STR];
31 char *tokens[MAX_TOKENS]; /* for du(1) output parse */
32 char *last, *p;
33 int i, ret;
34 FILE *fp;
35 prop_dictionary_t prd; /* root dictionary */
36 prop_dictionary_t pcd; /* child dictionary */
37 prop_number_t pn; /* for size in bytes */
38 prop_string_t ps; /* path name */
40 /* Initiate pipe stream to du(1) */
41 fp = popen("du", "r");
42 if (fp == NULL) {
43 perror("popen()");
44 exit(EXIT_FAILURE);
47 /* Create root dictionary */
48 prd = prop_dictionary_create_with_capacity(INIT_ROOT_CAPACITY);
49 if (prd == NULL) {
50 pclose(fp);
51 err(EXIT_FAILURE, "prop_dictionary_create_with_capacity()");
54 /* Read from stream */
55 while (fgets(str, MAX_STR, fp) != NULL) {
56 /* Parse output of du(1) command */
57 i = 0;
58 p = strtok_r(str, "\t", &last);
59 while (p && i < MAX_TOKENS - 1) {
60 tokens[i++] = p;
61 p = strtok_r(NULL, "\t", &last);
63 tokens[i] = NULL;
65 /* Trim '\n' from tokens[1] */
66 (tokens[1])[strlen(tokens[1]) - 1] = '\0';
68 /* Create child dictionary */
69 pcd = prop_dictionary_create_with_capacity(INIT_CHILD_CAPACITY);
70 if (pcd == NULL) {
71 prop_object_release(prd);
72 err(EXIT_FAILURE, "prop_dictionary_create_with_capacity()");
75 /* tokens[1] holds the path */
76 ps = prop_string_create_cstring(tokens[1]);
79 * tokens[0] holds the size in bytes
81 * We use a signed prop_number_t object, so that
82 * when externalized it will be represented as decimal
83 * (unsigned numbers are externalized in base-16).
85 * Note: atoi() does not detect errors, but we trust
86 * du(1) to provide us with valid input. Otherwise,
87 * we should use strtol(3) or sscanf(3).
89 pn = prop_number_create_integer(atoi(tokens[0]));
91 /* Add path to child dictionary */
92 if (prop_dictionary_set(pcd, "path", ps) == FALSE) {
93 prop_object_release(pn);
94 prop_object_release(ps);
95 prop_object_release(pcd);
96 prop_object_release(prd);
99 /* Add size to child dictionary */
100 if (prop_dictionary_set(pcd, "size in bytes", pn) == FALSE) {
101 prop_object_release(pn);
102 prop_object_release(pcd);
103 prop_object_release(prd);
104 err(EXIT_FAILURE, "prop_dictionary_set()");
107 /* Add child dictionary to root dictionary */
108 prop_dictionary_set(prd, tokens[1], pcd);
110 /* Release `pn' and `ps' */
111 prop_object_release(pn);
112 prop_object_release(ps);
114 /* Release child dictionary */
115 prop_object_release(pcd);
118 /* Externalize root dictionary to file in XML representation */
119 if (prop_dictionary_externalize_to_file(prd, "./data.xml") == FALSE) {
120 prop_object_release(prd);
121 err(EXIT_FAILURE, "prop_dictionary_externalize_to_file()");
124 /* Release root dictionary */
125 prop_object_release(prd);
127 /* Close pipe stream */
128 if (pclose(fp) == -1)
129 err(EXIT_FAILURE, "pclose()");
131 return EXIT_SUCCESS;