Introduction
Introduction Statistics Contact Development Disclaimer Help
get-started.tex - libzahl - big integer library
git clone git://git.suckless.org/libzahl
Log
Files
Refs
README
LICENSE
---
get-started.tex (6604B)
---
1 \chapter{Get started}
2 \label{chap:Get started}
3
4 In this chapter, you will learn the basics of libzahl.
5 You should read the sections in order.
6
7 \vspace{1cm}
8 \minitoc
9
10
11 % TODO add a section a linking and stuff here.
12
13
14 \newpage
15 \section{Initialisation}
16 \label{sec:Initialisation}
17
18 Before using libzahl, it must be initialised. When
19 initialising, you must select a location whither libzahl
20 long jumps on error.
21
22 \begin{alltt}
23 #include <zahl.h>
24
25 int
26 main(void)
27 \{
28 jmp_buf jmpenv;
29 if (setjmp(jmpenv))
30 return 1; \textcolor{c}{/* \textrm{Exit on error} */}
31 zsetup(jmpenv);
32 \textcolor{c}{/* \textrm{\ldots} */}
33 return 0;
34 \}
35 \end{alltt}
36
37 {\tt zsetup} also initialises temporary variables used
38 by libzahl's functions, and constants used by libzahl's
39 functions. Furthermore, it initialises the memory pool
40 and a stack which libzahl uses to keep track of temporary
41 allocations that need to be pooled for use if a function
42 fails.
43
44 It is recommended to also uninitialise libzahl when you
45 are done using it, for example before the program exits.
46
47 \begin{alltt}
48 \textcolor{c}{int
49 main(void)
50 \{
51 jmp_buf jmpenv;
52 if (setjmp(jmpenv))
53 return 1; /* \textrm{Exit on error} */
54 zsetup(jmpenv);
55 /* \textrm{\ldots} */}
56 zunsetup();
57 \textcolor{c}{return 0;
58 \}}
59 \end{alltt}
60
61 {\tt zunsetup} frees all memory that has been reclaimed to
62 the memory pool, and all memory allocated by {\tt zsetup}.
63 Note that this does not free integers that are still
64 in use. It is possible to simply call {\tt zunsetup}
65 directly followed by {\tt zsetup} to free all pooled
66 memory.
67
68
69 \newpage
70 \section{Exceptional conditions}
71 \label{sec:Exceptional conditions}
72
73 Exceptional conditions, casually called `errors',
74 are treated in libzahl using long jumps.
75
76 \begin{alltt}
77 int
78 main(int argc, char *argv[])
79 \{
80 jmp_buf jmpenv;
81 if (setjmp(jmpenv))
82 return 1; \textcolor{c}{/* \textrm{Exit on error} */}
83 zsetup(jmpenv);
84 return 0;
85 \}
86 \end{alltt}
87
88 Just exiting on error is not a particularly good
89 idea. Instead, you may want to print an error message.
90 This is done with {\tt zperror}.
91
92 \begin{alltt}
93 if (setjmp(jmpenv)) \{
94 zperror(\textcolor{c}{*argv});
95 \textcolor{c}{return 1;}
96 \}
97 \end{alltt}
98
99 \noindent
100 {\tt zperror} works just like {\tt perror}. It
101 outputs an error description to standard error.
102 A line break is printed at the end of the message.
103 If the argument passed to {\tt zperror} is neither
104 {\tt NULL} nor an empty string, it is printed in
105 front of the description, with a colon and a
106 space separating the passed string and the description.
107 For example, {\tt zperror("my-app")} may output
108
109 \begin{verbatim}
110 my-app: Cannot allocate memory
111 \end{verbatim}
112
113 libzahl also provides {\tt zerror}. Calling this
114 function will provide you with an error code and
115 a textual description.
116
117 \begin{alltt}
118 \textcolor{c}{if (setjmp(jmpenv)) \{}
119 const char *description;
120 zerror(&description);
121 fprintf(stderr, "\%s: \%s\verb|\|n", *argv, description);
122 \textcolor{c}{return 1;}
123 \textcolor{c}{\}}
124 \end{alltt}
125
126 \noindent
127 This code behaves like the example above that
128 calls {\tt zperror}. If you are interested in the
129 error code, you instead look at the return value.
130
131 \begin{alltt}
132 \textcolor{c}{if (setjmp(jmpenv)) \{}
133 enum zerror e = zerror(NULL);
134 switch (e) \{
135 case ZERROR_ERRNO_SET:
136 perror("");
137 \textcolor{c}{return 1;}
138 case ZERROR_0_POW_0:
139 fprintf(stderr, "Indeterminate form: 0^0\verb|\|n");
140 \textcolor{c}{return 1;}
141 case ZERROR_0_DIV_0:
142 fprintf(stderr, "Indeterminate form: 0/0\verb|\|n");
143 \textcolor{c}{return 1;}
144 case ZERROR_DIV_0:
145 fprintf(stderr, "Do not divide by zero, dummy\verb|\|n");
146 \textcolor{c}{return 1;}
147 case ZERROR_NEGATIVE:
148 fprintf(stderr, "Undefined (negative input)\verb|\|n");
149 \textcolor{c}{return 1;}
150 case ZERROR_INVALID_RADIX:
151 fprintf(stderr, "Radix must be at least 2\verb|\|n");
152 \textcolor{c}{return 1;}
153 default:
154 zperror("");
155 \textcolor{c}{return 1;}
156 \}
157 \textcolor{c}{\}}
158 \end{alltt}
159
160 To change the point whither libzahl's functions
161 jump, call {\tt setjmp} and {\tt zsetup} again.
162
163 \begin{alltt}
164 jmp_buf jmpenv;
165 if (setjmp(jmpenv)) \{
166 \textcolor{c}{/* \textrm{\ldots} */}
167 \}
168 zsetup(jmpenv);
169 \textcolor{c}{/* \textrm{\ldots} */}
170 if (setjmp(jmpenv)) \{
171 \textcolor{c}{/* \textrm{\ldots} */}
172 \}
173 zsetup(jmpenv);
174 \end{alltt}
175
176
177 \newpage
178 \section{Create an integer}
179 \label{sec:Create an integer}
180
181 To do any real work with libzahl, we need integers. The
182 data type for a big integer in libzahl is {\tt z\_t}
183 \psecref{sec:Integer structure}. Before a {\tt z\_t}
184 can be assigned a value, it must be initialised.
185
186 \begin{alltt}
187 z_t a;
188 \textcolor{c}{/* \textrm{\ldots} */
189 zsetup(jmpenv);}
190 zinit(a);
191 \textcolor{c}{/* \textrm{\ldots} */
192 zunsetup();}
193 \end{alltt}
194
195 \noindent
196 {\tt zinit(a)} is actually a less cumbersome and optimised
197 alternative to calling {\tt memset(a, 0, sizeof(z\_t))}.
198 It sets the values of two members: {\tt .alloced} and
199 {\tt .chars}, to 0 and {\tt NULL}. This is necessary,
200 otherwise the memory allocated could be fooled to deallocate
201 a false pointer, causing the program to abort.
202
203 Once the reference has been initialised, you may assign it
204 a value. The simplest way to do this is by calling
205
206 \begin{alltt}
207 void zseti(z_t a, int64_t value);
208 \end{alltt}
209
210 \noindent
211 For example {\tt zseti(a, 1)}, assignes the value 1 to
212 the {\tt z\_t} {\tt a}.
213
214 When you are done using a big integer reference, you should
215 call {\tt zfree} to let libzahl know that it should pool
216 the allocation of the {\tt .chars} member.
217
218 \begin{alltt}
219 z_t a;
220 zinit(a);
221 \textcolor{c}{/* \textrm{\ldots} */}
222 zfree(a); \textcolor{c}{/* \textrm{before \texttt{zunsetup}} */}
223 \end{alltt}
224
225 \noindent
226 Instead of calling {\tt zfree(a)}, it is possible — but
227 strongly discouraged — to call {\tt free(a->chars)}.
228 Note however, by doing so, the allocation is not pooled
229 for reuse.
230
231 If you plan to reuse the variable later, you need to
232 reinitialise it by calling {\tt zinit} again.
233
234 Alternatives to {\tt zseti} include \psecref{sec:Assignment}:
235
236 \begin{alltt}
237 void zsetu(z_t a, uint64_t value);
238 void zsets(z_t a, const char *value);
239 void zset(z_t a, z_t value); \textcolor{c}{/* \textrm{copy \texttt{va…
240 \end{alltt}
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.