├── .gitignore
├── LICENSE
├── README.md
├── api
├── enum
├── funcs
└── opts
├── project.janet
├── src
├── curl.c
└── khash.h
└── test
└── main.janet
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode
2 | src/build
3 | build
4 | test/DOWNLOAD
5 | tests/DOWNLOAD
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # jurl
2 |
3 | [janet](https://janet-lang.org/) wrapper around libcurl
4 |
5 | ## WIP
6 | is it not yet ready for production ;)
7 |
--------------------------------------------------------------------------------
/api/enum:
--------------------------------------------------------------------------------
1 | :=:
2 | CURLSSLBACKEND_NONE
3 | CURLSSLBACKEND_OPENSSL
4 | CURLSSLBACKEND_GNUTLS
5 | CURLSSLBACKEND_NSS
6 | CURLSSLBACKEND_OBSOLETE4
7 | CURLSSLBACKEND_GSKIT
8 | CURLSSLBACKEND_POLARSSL
9 | CURLSSLBACKEND_WOLFSSL
10 | CURLSSLBACKEND_SCHANNEL
11 | CURLSSLBACKEND_DARWINSSL
12 | CURLSSLBACKEND_AXTLS
13 | CURLSSLBACKEND_MBEDTLS
14 | CURLSSLBACKEND_MESALINK
15 | :=:
16 | CURLFILETYPE_FILE
17 | CURLFILETYPE_DIRECTORY
18 | CURLFILETYPE_SYMLINK
19 | CURLFILETYPE_DEVICE_BLOCK
20 | CURLFILETYPE_DEVICE_CHAR
21 | CURLFILETYPE_NAMEDPIPE
22 | CURLFILETYPE_SOCKET
23 | CURLFILETYPE_DOOR
24 | CURLFILETYPE_UNKNOWN
25 | :=:
26 | CURLSOCKTYPE_IPCXN
27 | CURLSOCKTYPE_ACCEPT
28 | CURLSOCKTYPE_LAST
29 | :=:
30 | CURLIOE_OK
31 | CURLIOE_UNKNOWNCMD
32 | CURLIOE_FAILRESTART
33 | CURLIOE_LAST
34 | :=:
35 | CURLIOCMD_NOP
36 | CURLIOCMD_RESTARTREAD
37 | CURLIOCMD_LAST
38 | :=:
39 | CURLINFO_TEXT
40 | CURLINFO_HEADER_IN
41 | CURLINFO_HEADER_OUT
42 | CURLINFO_DATA_IN
43 | CURLINFO_DATA_OUT
44 | CURLINFO_SSL_DATA_IN
45 | CURLINFO_SSL_DATA_OUT
46 | CURLINFO_END
47 | :=:
48 | CURLE_OK
49 | CURLE_UNSUPPORTED_PROTOCOL
50 | CURLE_FAILED_INIT
51 | CURLE_URL_MALFORMAT
52 | CURLE_NOT_BUILT_IN
53 | CURLE_COULDNT_RESOLVE_PROXY
54 | CURLE_COULDNT_RESOLVE_HOST
55 | CURLE_COULDNT_CONNECT
56 | CURLE_WEIRD_SERVER_REPLY
57 | CURLE_REMOTE_ACCESS_DENIED
58 | CURLE_FTP_ACCEPT_FAILED
59 | CURLE_FTP_WEIRD_PASS_REPLY
60 | CURLE_FTP_ACCEPT_TIMEOUT
61 | CURLE_FTP_WEIRD_PASV_REPLY
62 | CURLE_FTP_WEIRD_227_FORMAT
63 | CURLE_FTP_CANT_GET_HOST
64 | CURLE_HTTP2
65 | CURLE_FTP_COULDNT_SET_TYPE
66 | CURLE_PARTIAL_FILE
67 | CURLE_FTP_COULDNT_RETR_FILE
68 | CURLE_OBSOLETE20
69 | CURLE_QUOTE_ERROR
70 | CURLE_HTTP_RETURNED_ERROR
71 | CURLE_WRITE_ERROR
72 | CURLE_OBSOLETE24
73 | CURLE_UPLOAD_FAILED
74 | CURLE_READ_ERROR
75 | CURLE_OUT_OF_MEMORY
76 | CURLE_OPERATION_TIMEDOUT
77 | CURLE_OBSOLETE29
78 | CURLE_FTP_PORT_FAILED
79 | CURLE_FTP_COULDNT_USE_REST
80 | CURLE_OBSOLETE32
81 | CURLE_RANGE_ERROR
82 | CURLE_HTTP_POST_ERROR
83 | CURLE_SSL_CONNECT_ERROR
84 | CURLE_BAD_DOWNLOAD_RESUME
85 | CURLE_FILE_COULDNT_READ_FILE
86 | CURLE_LDAP_CANNOT_BIND
87 | CURLE_LDAP_SEARCH_FAILED
88 | CURLE_OBSOLETE40
89 | CURLE_FUNCTION_NOT_FOUND
90 | CURLE_ABORTED_BY_CALLBACK
91 | CURLE_BAD_FUNCTION_ARGUMENT
92 | CURLE_OBSOLETE44
93 | CURLE_INTERFACE_FAILED
94 | CURLE_OBSOLETE46
95 | CURLE_TOO_MANY_REDIRECTS
96 | CURLE_UNKNOWN_OPTION
97 | CURLE_TELNET_OPTION_SYNTAX
98 | CURLE_OBSOLETE50
99 | CURLE_OBSOLETE51
100 | CURLE_GOT_NOTHING
101 | CURLE_SSL_ENGINE_NOTFOUND
102 | CURLE_SSL_ENGINE_SETFAILED
103 | CURLE_SEND_ERROR
104 | CURLE_RECV_ERROR
105 | CURLE_OBSOLETE57
106 | CURLE_SSL_CERTPROBLEM
107 | CURLE_SSL_CIPHER
108 | CURLE_PEER_FAILED_VERIFICATION
109 | CURLE_BAD_CONTENT_ENCODING
110 | CURLE_LDAP_INVALID_URL
111 | CURLE_FILESIZE_EXCEEDED
112 | CURLE_USE_SSL_FAILED
113 | CURLE_SEND_FAIL_REWIND
114 | CURLE_SSL_ENGINE_INITFAILED
115 | CURLE_LOGIN_DENIED
116 | CURLE_TFTP_NOTFOUND
117 | CURLE_TFTP_PERM
118 | CURLE_REMOTE_DISK_FULL
119 | CURLE_TFTP_ILLEGAL
120 | CURLE_TFTP_UNKNOWNID
121 | CURLE_REMOTE_FILE_EXISTS
122 | CURLE_TFTP_NOSUCHUSER
123 | CURLE_CONV_FAILED
124 | CURLE_CONV_REQD
125 | CURLE_SSL_CACERT_BADFILE
126 | CURLE_REMOTE_FILE_NOT_FOUND
127 | CURLE_SSH
128 | CURLE_SSL_SHUTDOWN_FAILED
129 | CURLE_AGAIN
130 | CURLE_SSL_CRL_BADFILE
131 | CURLE_SSL_ISSUER_ERROR
132 | CURLE_FTP_PRET_FAILED
133 | CURLE_RTSP_CSEQ_ERROR
134 | CURLE_RTSP_SESSION_ERROR
135 | CURLE_FTP_BAD_FILE_LIST
136 | CURLE_CHUNK_FAILED
137 | CURLE_NO_CONNECTION_AVAILABLE
138 | CURLE_SSL_PINNEDPUBKEYNOTMATCH
139 | CURLE_SSL_INVALIDCERTSTATUS
140 | CURLE_HTTP2_STREAM
141 | CURLE_RECURSIVE_API_CALL
142 | :=:
143 | CURLPROXY_HTTP
144 | CURLPROXY_HTTP_1_0
145 | CURLPROXY_HTTPS
146 | CURLPROXY_SOCKS4
147 | CURLPROXY_SOCKS5
148 | CURLPROXY_SOCKS4A
149 | CURLPROXY_SOCKS5_HOSTNAME
150 | :=:
151 | CURLUSESSL_NONE
152 | CURLUSESSL_TRY
153 | CURLUSESSL_CONTROL
154 | CURLUSESSL_ALL
155 | CURLUSESSL_LAST
156 | :=:
157 | CURLFTPSSL_CCC_NONE
158 | CURLFTPSSL_CCC_PASSIVE
159 | CURLFTPSSL_CCC_ACTIVE
160 | CURLFTPSSL_CCC_LAST
161 | :=:
162 | CURLFTPAUTH_DEFAULT
163 | CURLFTPAUTH_SSL
164 | CURLFTPAUTH_TLS
165 | CURLFTPAUTH_LAST
166 | :=:
167 | CURLFTP_CREATE_DIR_NONE
168 | CURLFTP_CREATE_DIR
169 | CURLFTP_CREATE_DIR_RETRY
170 | CURLFTP_CREATE_DIR_LAST
171 | :=:
172 | CURLFTPMETHOD_DEFAULT
173 | CURLFTPMETHOD_MULTICWD
174 | CURLFTPMETHOD_NOCWD
175 | CURLFTPMETHOD_SINGLECWD
176 | CURLFTPMETHOD_LAST
177 | :=:
178 | CURL_HTTP_VERSION_NONE
179 | CURL_HTTP_VERSION_1_0
180 | CURL_HTTP_VERSION_1_1
181 | CURL_HTTP_VERSION_2_0
182 | CURL_HTTP_VERSION_2TLS
183 | CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE
184 | CURL_HTTP_VERSION_LAST
185 | :=:
186 | CURL_RTSPREQ_NONE
187 | CURL_RTSPREQ_OPTIONS
188 | CURL_RTSPREQ_DESCRIBE
189 | CURL_RTSPREQ_ANNOUNCE
190 | CURL_RTSPREQ_SETUP
191 | CURL_RTSPREQ_PLAY
192 | CURL_RTSPREQ_PAUSE
193 | CURL_RTSPREQ_TEARDOWN
194 | CURL_RTSPREQ_GET_PARAMETER
195 | CURL_RTSPREQ_SET_PARAMETER
196 | CURL_RTSPREQ_RECORD
197 | CURL_RTSPREQ_RECEIVE
198 | CURL_RTSPREQ_LAST
199 | :=:
200 | CURL_SSLVERSION_DEFAULT
201 | CURL_SSLVERSION_TLSv1
202 | CURL_SSLVERSION_SSLv2
203 | CURL_SSLVERSION_SSLv3
204 | CURL_SSLVERSION_TLSv1_0
205 | CURL_SSLVERSION_TLSv1_1
206 | CURL_SSLVERSION_TLSv1_2
207 | CURL_SSLVERSION_TLSv1_3
208 | CURL_SSLVERSION_LAST
209 | :=:
210 | CURL_SSLVERSION_MAX_NONE
211 | CURL_SSLVERSION_MAX_DEFAULT
212 | CURL_SSLVERSION_MAX_TLSv1_0
213 | CURL_SSLVERSION_MAX_TLSv1_1
214 | CURL_SSLVERSION_MAX_TLSv1_2
215 | CURL_SSLVERSION_MAX_TLSv1_3
216 | CURL_SSLVERSION_MAX_LAST
217 | :=:
218 | CURL_TIMECOND_NONE
219 | CURL_TIMECOND_IFMODSINCE
220 | CURL_TIMECOND_IFUNMODSINCE
221 | CURL_TIMECOND_LASTMOD
222 | CURL_TIMECOND_LAST
223 | :=:
224 | CURLFORM_NOTHING
225 | CURLFORM_COPYNAME
226 | CURLFORM_PTRNAME
227 | CURLFORM_NAMELENGTH
228 | CURLFORM_COPYCONTENTS
229 | CURLFORM_PTRCONTENTS
230 | CURLFORM_CONTENTSLENGTH
231 | CURLFORM_FILECONTENT
232 | CURLFORM_ARRAY
233 | CURLFORM_OBSOLETE
234 | CURLFORM_FILE
235 | CURLFORM_BUFFER
236 | CURLFORM_BUFFERPTR
237 | CURLFORM_BUFFERLENGTH
238 | CURLFORM_CONTENTTYPE
239 | CURLFORM_CONTENTHEADER
240 | CURLFORM_FILENAME
241 | CURLFORM_END
242 | CURLFORM_OBSOLETE2
243 | CURLFORM_STREAM
244 | CURLFORM_CONTENTLEN
245 | CURLFORM_LASTENTRY
246 | :=:
247 | CURL_FORMADD_OK
248 | CURL_FORMADD_MEMORY
249 | CURL_FORMADD_OPTION_TWICE
250 | CURL_FORMADD_NULL
251 | CURL_FORMADD_UNKNOWN_OPTION
252 | CURL_FORMADD_INCOMPLETE
253 | CURL_FORMADD_ILLEGAL_ARRAY
254 | CURL_FORMADD_DISABLED
255 | CURL_FORMADD_LAST
256 | :=:
257 | CURLSSLSET_OK
258 | CURLSSLSET_UNKNOWN_BACKEND
259 | CURLSSLSET_TOO_LATE
260 | CURLSSLSET_NO_BACKENDS
261 | :=:
262 | CURLINFO_NONE
263 | CURLINFO_EFFECTIVE_URL
264 | CURLINFO_RESPONSE_CODE
265 | CURLINFO_TOTAL_TIME
266 | CURLINFO_NAMELOOKUP_TIME
267 | CURLINFO_CONNECT_TIME
268 | CURLINFO_PRETRANSFER_TIME
269 | CURLINFO_SIZE_UPLOAD
270 | CURLINFO_SIZE_UPLOAD_T
271 | CURLINFO_SIZE_DOWNLOAD
272 | CURLINFO_SIZE_DOWNLOAD_T
273 | CURLINFO_SPEED_DOWNLOAD
274 | CURLINFO_SPEED_DOWNLOAD_T
275 | CURLINFO_SPEED_UPLOAD
276 | CURLINFO_SPEED_UPLOAD_T
277 | CURLINFO_HEADER_SIZE
278 | CURLINFO_REQUEST_SIZE
279 | CURLINFO_SSL_VERIFYRESULT
280 | CURLINFO_FILETIME
281 | CURLINFO_FILETIME_T
282 | CURLINFO_CONTENT_LENGTH_DOWNLOAD
283 | CURLINFO_CONTENT_LENGTH_DOWNLOAD_T
284 | CURLINFO_CONTENT_LENGTH_UPLOAD
285 | CURLINFO_CONTENT_LENGTH_UPLOAD_T
286 | CURLINFO_STARTTRANSFER_TIME
287 | CURLINFO_CONTENT_TYPE
288 | CURLINFO_REDIRECT_TIME
289 | CURLINFO_REDIRECT_COUNT
290 | CURLINFO_PRIVATE
291 | CURLINFO_HTTP_CONNECTCODE
292 | CURLINFO_HTTPAUTH_AVAIL
293 | CURLINFO_PROXYAUTH_AVAIL
294 | CURLINFO_OS_ERRNO
295 | CURLINFO_NUM_CONNECTS
296 | CURLINFO_SSL_ENGINES
297 | CURLINFO_COOKIELIST
298 | CURLINFO_LASTSOCKET
299 | CURLINFO_FTP_ENTRY_PATH
300 | CURLINFO_REDIRECT_URL
301 | CURLINFO_PRIMARY_IP
302 | CURLINFO_APPCONNECT_TIME
303 | CURLINFO_CERTINFO
304 | CURLINFO_CONDITION_UNMET
305 | CURLINFO_RTSP_SESSION_ID
306 | CURLINFO_RTSP_CLIENT_CSEQ
307 | CURLINFO_RTSP_SERVER_CSEQ
308 | CURLINFO_RTSP_CSEQ_RECV
309 | CURLINFO_PRIMARY_PORT
310 | CURLINFO_LOCAL_IP
311 | CURLINFO_LOCAL_PORT
312 | CURLINFO_TLS_SESSION
313 | CURLINFO_ACTIVESOCKET
314 | CURLINFO_TLS_SSL_PTR
315 | CURLINFO_HTTP_VERSION
316 | CURLINFO_PROXY_SSL_VERIFYRESULT
317 | CURLINFO_PROTOCOL
318 | CURLINFO_SCHEME
319 | CURLINFO_TOTAL_TIME_T
320 | CURLINFO_NAMELOOKUP_TIME_T
321 | CURLINFO_CONNECT_TIME_T
322 | CURLINFO_PRETRANSFER_TIME_T
323 | CURLINFO_STARTTRANSFER_TIME_T
324 | CURLINFO_REDIRECT_TIME_T
325 | CURLINFO_APPCONNECT_TIME_T
326 | CURLINFO_LASTONE
327 | :=:
328 | CURLCLOSEPOLICY_NONE
329 | CURLCLOSEPOLICY_OLDEST
330 | CURLCLOSEPOLICY_LEAST_RECENTLY_USED
331 | CURLCLOSEPOLICY_LEAST_TRAFFIC
332 | CURLCLOSEPOLICY_SLOWEST
333 | CURLCLOSEPOLICY_CALLBACK
334 | CURLCLOSEPOLICY_LAST
335 | :=:
336 | CURL_LOCK_DATA_NONE
337 | CURL_LOCK_DATA_SHARE
338 | CURL_LOCK_DATA_COOKIE
339 | CURL_LOCK_DATA_DNS
340 | CURL_LOCK_DATA_SSL_SESSION
341 | CURL_LOCK_DATA_CONNECT
342 | CURL_LOCK_DATA_PSL
343 | CURL_LOCK_DATA_LAST
344 | :=:
345 | CURL_LOCK_ACCESS_NONE
346 | CURL_LOCK_ACCESS_SHARED
347 | CURL_LOCK_ACCESS_SINGLE
348 | CURL_LOCK_ACCESS_LAST
349 | :=:
350 | CURLSHE_OK
351 | CURLSHE_BAD_OPTION
352 | CURLSHE_IN_USE
353 | CURLSHE_INVALID
354 | CURLSHE_NOMEM
355 | CURLSHE_NOT_BUILT_IN
356 | CURLSHE_LAST
357 | :=:
358 | CURLSHOPT_NONE
359 | CURLSHOPT_SHARE
360 | CURLSHOPT_UNSHARE
361 | CURLSHOPT_LOCKFUNC
362 | CURLSHOPT_UNLOCKFUNC
363 | CURLSHOPT_USERDATA
364 | CURLSHOPT_LAST
365 | :=:
--------------------------------------------------------------------------------
/api/funcs:
--------------------------------------------------------------------------------
1 | [x] => curl_easy_init
2 | [x] => curl_easy_cleanup
3 | [x] => curl_easy_duphandle
4 | [x] => curl_easy_escape
5 | [x] => curl_easy_unescape
6 | [x] => curl_easy_strerror
7 | [x] => curl_easy_pause
8 | [x] => curl_easy_reset
9 | [x] => curl_easy_upkeep
10 | [x] => curl_easy_recv
11 | [x] => curl_easy_send
12 | [x] => curl_easy_perform
13 | [~] => curl_easy_setopt
14 | [~] => curl_easy_getinfo
15 |
16 | [x] => curl_share_cleanup
17 | [x] => curl_share_init
18 | [x] => curl_share_strerror
19 | [?] => curl_share_setopt => i need to learn more about this function, do we really need 'share' at all
20 |
21 | [x] => curl_url
22 | [x] => curl_url_cleanup
23 | [x] => curl_url_dup
24 | [x] => curl_url_get
25 | [x] => curl_url_set
26 |
27 | [x] => curl_mime_init
28 | [x] => curl_mime_free
29 | [x] => curl_mime_addpart
30 | [x] => curl_mime_subparts
31 | [x] => curl_mime_name
32 | [x] => curl_mime_type
33 | [x] => curl_mime_data
34 | [x] => curl_mime_encoder
35 | [x] => curl_mime_headers
36 | [x] => curl_mime_filedata
37 | [x] => curl_mime_filename
38 | [?] => curl_mime_data_cb
39 |
40 | [ ] => curl_multi_add_handle
41 | [ ] => curl_multi_assign
42 | [ ] => curl_multi_cleanup
43 | [ ] => curl_multi_fdset
44 | [ ] => curl_multi_info_read
45 | [ ] => curl_multi_init
46 | [ ] => curl_multi_perform
47 | [ ] => curl_multi_remove_handle
48 | [ ] => curl_multi_setopt
49 | [ ] => curl_multi_socket_action
50 | [ ] => curl_multi_strerror
51 | [ ] => curl_multi_timeout
52 | [ ] => curl_multi_wait
53 |
54 | [ ] => curl_pushheader_byname
55 | [ ] => curl_pushheader_bynum
56 |
57 | // deprecated or N/A or stupid
58 |
59 | [-] => curl_slist_append
60 | [-] => curl_slist_free_all
61 |
62 | [-] => curl_version
63 | [-] => curl_version_info
64 |
65 | [-] => curl_free
66 | [-] => curl_getdate
67 |
68 | [-] => curl_global_cleanup
69 | [-] => curl_global_init
70 | [-] => curl_global_init_mem
71 | [-] => curl_global_sslset
72 |
73 | [-] => curl_formadd
74 | [-] => curl_formfree
75 | [-] => curl_formget
--------------------------------------------------------------------------------
/api/opts:
--------------------------------------------------------------------------------
1 | CURLOPT_WRITEDATA @=> writedata #=> OBJECTPOINT
2 | CURLOPT_READDATA @=> readdata #=> OBJECTPOINT
3 | CURLOPT_ERRORBUFFER @=> errorbuffer #=> OBJECTPOINT
4 | CURLOPT_POSTFIELDS @=> postfields #=> OBJECTPOINT
5 | CURLOPT_HTTPHEADER @=> httpheader #=> OBJECTPOINT
6 | CURLOPT_HTTPPOST @=> httppost #=> OBJECTPOINT
7 | CURLOPT_QUOTE @=> quote #=> OBJECTPOINT
8 | CURLOPT_HEADERDATA @=> headerdata #=> OBJECTPOINT
9 | CURLOPT_STDERR @=> stderr #=> OBJECTPOINT
10 | CURLOPT_POSTQUOTE @=> postquote #=> OBJECTPOINT
11 | CURLOPT_OBSOLETE40 @=> obsolete40 #=> OBJECTPOINT
12 | CURLOPT_PROGRESSDATA @=> progressdata #=> OBJECTPOINT
13 | CURLOPT_TELNETOPTIONS @=> telnetoptions #=> OBJECTPOINT
14 | CURLOPT_PREQUOTE @=> prequote #=> OBJECTPOINT
15 | CURLOPT_DEBUGDATA @=> debugdata #=> OBJECTPOINT
16 | CURLOPT_SHARE @=> share #=> OBJECTPOINT
17 | CURLOPT_PRIVATE @=> private #=> OBJECTPOINT
18 | CURLOPT_HTTP200ALIASES @=> http200-aliases #=> OBJECTPOINT
19 | CURLOPT_SSL_CTX_DATA @=> ssl-ctx-data #=> OBJECTPOINT
20 | CURLOPT_IOCTLDATA @=> ioctldata #=> OBJECTPOINT
21 | CURLOPT_SOCKOPTDATA @=> sockoptdata #=> OBJECTPOINT
22 | CURLOPT_OPENSOCKETDATA @=> opensocketdata #=> OBJECTPOINT
23 | CURLOPT_COPYPOSTFIELDS @=> copypostfields #=> OBJECTPOINT
24 | CURLOPT_SEEKDATA @=> seekdata #=> OBJECTPOINT
25 | CURLOPT_SSH_KEYDATA @=> ssh-keydata #=> OBJECTPOINT
26 | CURLOPT_MAIL_RCPT @=> mail-rcpt #=> OBJECTPOINT
27 | CURLOPT_INTERLEAVEDATA @=> interleavedata #=> OBJECTPOINT
28 | CURLOPT_CHUNK_DATA @=> chunk-data #=> OBJECTPOINT
29 | CURLOPT_FNMATCH_DATA @=> fnmatch-data #=> OBJECTPOINT
30 | CURLOPT_RESOLVE @=> resolve #=> OBJECTPOINT
31 | CURLOPT_CLOSESOCKETDATA @=> closesocketdata #=> OBJECTPOINT
32 | CURLOPT_PROXYHEADER @=> proxyheader #=> OBJECTPOINT
33 | CURLOPT_STREAM_DEPENDS @=> stream-depends #=> OBJECTPOINT
34 | CURLOPT_STREAM_DEPENDS_E @=> stream-depends-e #=> OBJECTPOINT
35 | CURLOPT_CONNECT_TO @=> connect-to #=> OBJECTPOINT
36 | CURLOPT_MIMEPOST @=> mimepost #=> OBJECTPOINT
37 | CURLOPT_RESOLVER_START_DATA @=> resolver-start-data #=> OBJECTPOINT
38 | CURLOPT_CURLU @=> curlu #=> OBJECTPOINT
39 | CURLOPT_TRAILERDATA @=> trailerdata #=> OBJECTPOINT
40 |
41 | :=:
42 |
43 | CURLOPT_URL @=> url #=> STRINGPOINT
44 | CURLOPT_PROXY @=> proxy #=> STRINGPOINT
45 | CURLOPT_USERPWD @=> userpwd #=> STRINGPOINT
46 | CURLOPT_PROXYUSERPWD @=> proxyuserpwd #=> STRINGPOINT
47 | CURLOPT_RANGE @=> range #=> STRINGPOINT
48 | CURLOPT_REFERER @=> referer #=> STRINGPOINT
49 | CURLOPT_FTPPORT @=> ftpport #=> STRINGPOINT
50 | CURLOPT_USERAGENT @=> useragent #=> STRINGPOINT
51 | CURLOPT_COOKIE @=> cookie #=> STRINGPOINT
52 | CURLOPT_SSLCERT @=> sslcert #=> STRINGPOINT
53 | CURLOPT_KEYPASSWD @=> keypasswd #=> STRINGPOINT
54 | CURLOPT_COOKIEFILE @=> cookiefile #=> STRINGPOINT
55 | CURLOPT_CUSTOMREQUEST @=> customrequest #=> STRINGPOINT
56 | CURLOPT_INTERFACE @=> interface #=> STRINGPOINT
57 | CURLOPT_KRBLEVEL @=> krblevel #=> STRINGPOINT
58 | CURLOPT_CAINFO @=> cainfo #=> STRINGPOINT
59 | CURLOPT_RANDOM_FILE @=> random-file #=> STRINGPOINT
60 | CURLOPT_EGDSOCKET @=> egdsocket #=> STRINGPOINT
61 | CURLOPT_COOKIEJAR @=> cookiejar #=> STRINGPOINT
62 | CURLOPT_SSL_CIPHER_LIST @=> ssl-cipher-list #=> STRINGPOINT
63 | CURLOPT_SSLCERTTYPE @=> sslcerttype #=> STRINGPOINT
64 | CURLOPT_SSLKEY @=> sslkey #=> STRINGPOINT
65 | CURLOPT_SSLKEYTYPE @=> sslkeytype #=> STRINGPOINT
66 | CURLOPT_SSLENGINE @=> sslengine #=> STRINGPOINT
67 | CURLOPT_CAPATH @=> capath #=> STRINGPOINT
68 | CURLOPT_ACCEPT_ENCODING @=> accept-encoding #=> STRINGPOINT
69 | CURLOPT_NETRC_FILE @=> netrc-file #=> STRINGPOINT
70 | CURLOPT_FTP_ACCOUNT @=> ftp-account #=> STRINGPOINT
71 | CURLOPT_COOKIELIST @=> cookielist #=> STRINGPOINT
72 | CURLOPT_FTP_ALTERNATIVE_TO_USER @=> ftp-alternative-to-user #=> STRINGPOINT
73 | CURLOPT_SSH_PUBLIC_KEYFILE @=> ssh-public-keyfile #=> STRINGPOINT
74 | CURLOPT_SSH_PRIVATE_KEYFILE @=> ssh-private-keyfile #=> STRINGPOINT
75 | CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 @=> ssh-host-public-key-md5 #=> STRINGPOINT
76 | CURLOPT_CRLFILE @=> crlfile #=> STRINGPOINT
77 | CURLOPT_ISSUERCERT @=> issuercert #=> STRINGPOINT
78 | CURLOPT_USERNAME @=> username #=> STRINGPOINT
79 | CURLOPT_PASSWORD @=> password #=> STRINGPOINT
80 | CURLOPT_PROXYUSERNAME @=> proxyusername #=> STRINGPOINT
81 | CURLOPT_PROXYPASSWORD @=> proxypassword #=> STRINGPOINT
82 | CURLOPT_NOPROXY @=> noproxy #=> STRINGPOINT
83 | CURLOPT_SOCKS5_GSSAPI_SERVICE @=> socks5-gssapi-service #=> STRINGPOINT
84 | CURLOPT_SSH_KNOWNHOSTS @=> ssh-knownhosts #=> STRINGPOINT
85 | CURLOPT_MAIL_FROM @=> mail-from #=> STRINGPOINT
86 | CURLOPT_RTSP_SESSION_ID @=> rtsp-session-id #=> STRINGPOINT
87 | CURLOPT_RTSP_STREAM_URI @=> rtsp-stream-uri #=> STRINGPOINT
88 | CURLOPT_RTSP_TRANSPORT @=> rtsp-transport #=> STRINGPOINT
89 | CURLOPT_TLSAUTH_USERNAME @=> tlsauth-username #=> STRINGPOINT
90 | CURLOPT_TLSAUTH_PASSWORD @=> tlsauth-password #=> STRINGPOINT
91 | CURLOPT_TLSAUTH_TYPE @=> tlsauth-type #=> STRINGPOINT
92 | CURLOPT_DNS_SERVERS @=> dns-servers #=> STRINGPOINT
93 | CURLOPT_MAIL_AUTH @=> mail-auth #=> STRINGPOINT
94 | CURLOPT_XOAUTH2_BEARER @=> xoauth2-bearer #=> STRINGPOINT
95 | CURLOPT_DNS_INTERFACE @=> dns-interface #=> STRINGPOINT
96 | CURLOPT_DNS_LOCAL_IP4 @=> dns-local-ip4 #=> STRINGPOINT
97 | CURLOPT_DNS_LOCAL_IP6 @=> dns-local-ip6 #=> STRINGPOINT
98 | CURLOPT_LOGIN_OPTIONS @=> login-options #=> STRINGPOINT
99 | CURLOPT_PINNEDPUBLICKEY @=> pinnedpublickey #=> STRINGPOINT
100 | CURLOPT_UNIX_SOCKET_PATH @=> unix-socket-path #=> STRINGPOINT
101 | CURLOPT_PROXY_SERVICE_NAME @=> proxy-service-name #=> STRINGPOINT
102 | CURLOPT_SERVICE_NAME @=> service-name #=> STRINGPOINT
103 | CURLOPT_DEFAULT_PROTOCOL @=> default-protocol #=> STRINGPOINT
104 | CURLOPT_PROXY_CAINFO @=> proxy-cainfo #=> STRINGPOINT
105 | CURLOPT_PROXY_CAPATH @=> proxy-capath #=> STRINGPOINT
106 | CURLOPT_PROXY_TLSAUTH_USERNAME @=> proxy-tlsauth-username #=> STRINGPOINT
107 | CURLOPT_PROXY_TLSAUTH_PASSWORD @=> proxy-tlsauth-password #=> STRINGPOINT
108 | CURLOPT_PROXY_TLSAUTH_TYPE @=> proxy-tlsauth-type #=> STRINGPOINT
109 | CURLOPT_PROXY_SSLCERT @=> proxy-sslcert #=> STRINGPOINT
110 | CURLOPT_PROXY_SSLCERTTYPE @=> proxy-sslcerttype #=> STRINGPOINT
111 | CURLOPT_PROXY_SSLKEY @=> proxy-sslkey #=> STRINGPOINT
112 | CURLOPT_PROXY_SSLKEYTYPE @=> proxy-sslkeytype #=> STRINGPOINT
113 | CURLOPT_PROXY_KEYPASSWD @=> proxy-keypasswd #=> STRINGPOINT
114 | CURLOPT_PROXY_SSL_CIPHER_LIST @=> proxy-ssl-cipher-list #=> STRINGPOINT
115 | CURLOPT_PROXY_CRLFILE @=> proxy-crlfile #=> STRINGPOINT
116 | CURLOPT_PRE_PROXY @=> pre-proxy #=> STRINGPOINT
117 | CURLOPT_PROXY_PINNEDPUBLICKEY @=> proxy-pinnedpublickey #=> STRINGPOINT
118 | CURLOPT_ABSTRACT_UNIX_SOCKET @=> abstract-unix-socket #=> STRINGPOINT
119 | CURLOPT_REQUEST_TARGET @=> request-target #=> STRINGPOINT
120 | CURLOPT_TLS13_CIPHERS @=> tls13-ciphers #=> STRINGPOINT
121 | CURLOPT_PROXY_TLS13_CIPHERS @=> proxy-tls13-ciphers #=> STRINGPOINT
122 | CURLOPT_DOH_URL @=> doh-url #=> STRINGPOINT
123 |
124 | :=:
125 |
126 | CURLOPT_PORT @=> port #=> LONG
127 | CURLOPT_TIMEOUT @=> timeout #=> LONG
128 | CURLOPT_INFILESIZE @=> infilesize #=> LONG
129 | CURLOPT_LOW_SPEED_LIMIT @=> low-speed-limit #=> LONG
130 | CURLOPT_LOW_SPEED_TIME @=> low-speed-time #=> LONG
131 | CURLOPT_RESUME_FROM @=> resume-from #=> LONG
132 | CURLOPT_CRLF @=> crlf #=> LONG
133 | CURLOPT_SSLVERSION @=> sslversion #=> LONG
134 | CURLOPT_TIMECONDITION @=> timecondition #=> LONG
135 | CURLOPT_TIMEVALUE @=> timevalue #=> LONG
136 | CURLOPT_VERBOSE @=> verbose #=> LONG
137 | CURLOPT_HEADER @=> header #=> LONG
138 | CURLOPT_NOPROGRESS @=> noprogress #=> LONG
139 | CURLOPT_NOBODY @=> nobody #=> LONG
140 | CURLOPT_FAILONERROR @=> failonerror #=> LONG
141 | CURLOPT_UPLOAD @=> upload #=> LONG
142 | CURLOPT_POST @=> post #=> LONG
143 | CURLOPT_DIRLISTONLY @=> dirlistonly #=> LONG
144 | CURLOPT_APPEND @=> append #=> LONG
145 | CURLOPT_NETRC @=> netrc #=> LONG
146 | CURLOPT_FOLLOWLOCATION @=> followlocation #=> LONG
147 | CURLOPT_TRANSFERTEXT @=> transfertext #=> LONG
148 | CURLOPT_PUT @=> put #=> LONG
149 | CURLOPT_AUTOREFERER @=> autoreferer #=> LONG
150 | CURLOPT_PROXYPORT @=> proxyport #=> LONG
151 | CURLOPT_POSTFIELDSIZE @=> postfieldsize #=> LONG
152 | CURLOPT_HTTPPROXYTUNNEL @=> httpproxytunnel #=> LONG
153 | CURLOPT_SSL_VERIFYPEER @=> ssl-verifypeer #=> LONG
154 | CURLOPT_MAXREDIRS @=> maxredirs #=> LONG
155 | CURLOPT_FILETIME @=> filetime #=> LONG
156 | CURLOPT_MAXCONNECTS @=> maxconnects #=> LONG
157 | CURLOPT_OBSOLETE72 @=> obsolete72 #=> LONG
158 | CURLOPT_FRESH_CONNECT @=> fresh-connect #=> LONG
159 | CURLOPT_FORBID_REUSE @=> forbid-reuse #=> LONG
160 | CURLOPT_CONNECTTIMEOUT @=> connecttimeout #=> LONG
161 | CURLOPT_HTTPGET @=> httpget #=> LONG
162 | CURLOPT_SSL_VERIFYHOST @=> ssl-verifyhost #=> LONG
163 | CURLOPT_HTTP_VERSION @=> http-version #=> LONG
164 | CURLOPT_FTP_USE_EPSV @=> ftp-use-epsv #=> LONG
165 | CURLOPT_SSLENGINE_DEFAULT @=> sslengine-default #=> LONG
166 | CURLOPT_DNS_USE_GLOBAL_CACHE @=> dns-use-global-cache #=> LONG
167 | CURLOPT_DNS_CACHE_TIMEOUT @=> dns-cache-timeout #=> LONG
168 | CURLOPT_COOKIESESSION @=> cookiesession #=> LONG
169 | CURLOPT_BUFFERSIZE @=> buffersize #=> LONG
170 | CURLOPT_NOSIGNAL @=> nosignal #=> LONG
171 | CURLOPT_PROXYTYPE @=> proxytype #=> LONG
172 | CURLOPT_UNRESTRICTED_AUTH @=> unrestricted-auth #=> LONG
173 | CURLOPT_FTP_USE_EPRT @=> ftp-use-eprt #=> LONG
174 | CURLOPT_HTTPAUTH @=> httpauth #=> LONG
175 | CURLOPT_FTP_CREATE_MISSING_DIRS @=> ftp-create-missing-dirs #=> LONG
176 | CURLOPT_PROXYAUTH @=> proxyauth #=> LONG
177 | CURLOPT_FTP_RESPONSE_TIMEOUT @=> ftp-response-timeout #=> LONG
178 | CURLOPT_IPRESOLVE @=> ipresolve #=> LONG
179 | CURLOPT_MAXFILESIZE @=> maxfilesize #=> LONG
180 | CURLOPT_USE_SSL @=> use-ssl #=> LONG
181 | CURLOPT_TCP_NODELAY @=> tcp-nodelay #=> LONG
182 | CURLOPT_FTPSSLAUTH @=> ftpsslauth #=> LONG
183 | CURLOPT_IGNORE_CONTENT_LENGTH @=> ignore-content-length #=> LONG
184 | CURLOPT_FTP_SKIP_PASV_IP @=> ftp-skip-pasv-ip #=> LONG
185 | CURLOPT_FTP_FILEMETHOD @=> ftp-filemethod #=> LONG
186 | CURLOPT_LOCALPORT @=> localport #=> LONG
187 | CURLOPT_LOCALPORTRANGE @=> localportrange #=> LONG
188 | CURLOPT_CONNECT_ONLY @=> connect-only #=> LONG
189 | CURLOPT_SSL_SESSIONID_CACHE @=> ssl-sessionid-cache #=> LONG
190 | CURLOPT_SSH_AUTH_TYPES @=> ssh-auth-types #=> LONG
191 | CURLOPT_FTP_SSL_CCC @=> ftp-ssl-ccc #=> LONG
192 | CURLOPT_TIMEOUT_MS @=> timeout-ms #=> LONG
193 | CURLOPT_CONNECTTIMEOUT_MS @=> connecttimeout-ms #=> LONG
194 | CURLOPT_HTTP_TRANSFER_DECODING @=> http-transfer-decoding #=> LONG
195 | CURLOPT_HTTP_CONTENT_DECODING @=> http-content-decoding #=> LONG
196 | CURLOPT_NEW_FILE_PERMS @=> new-file-perms #=> LONG
197 | CURLOPT_NEW_DIRECTORY_PERMS @=> new-directory-perms #=> LONG
198 | CURLOPT_POSTREDIR @=> postredir #=> LONG
199 | CURLOPT_PROXY_TRANSFER_MODE @=> proxy-transfer-mode #=> LONG
200 | CURLOPT_ADDRESS_SCOPE @=> address-scope #=> LONG
201 | CURLOPT_CERTINFO @=> certinfo #=> LONG
202 | CURLOPT_TFTP_BLKSIZE @=> tftp-blksize #=> LONG
203 | CURLOPT_SOCKS5_GSSAPI_NEC @=> socks5-gssapi-nec #=> LONG
204 | CURLOPT_PROTOCOLS @=> protocols #=> LONG
205 | CURLOPT_REDIR_PROTOCOLS @=> redir-protocols #=> LONG
206 | CURLOPT_FTP_USE_PRET @=> ftp-use-pret #=> LONG
207 | CURLOPT_RTSP_REQUEST @=> rtsp-request #=> LONG
208 | CURLOPT_RTSP_CLIENT_CSEQ @=> rtsp-client-cseq #=> LONG
209 | CURLOPT_RTSP_SERVER_CSEQ @=> rtsp-server-cseq #=> LONG
210 | CURLOPT_WILDCARDMATCH @=> wildcardmatch #=> LONG
211 | CURLOPT_TRANSFER_ENCODING @=> transfer-encoding #=> LONG
212 | CURLOPT_GSSAPI_DELEGATION @=> gssapi-delegation #=> LONG
213 | CURLOPT_ACCEPTTIMEOUT_MS @=> accepttimeout-ms #=> LONG
214 | CURLOPT_TCP_KEEPALIVE @=> tcp-keepalive #=> LONG
215 | CURLOPT_TCP_KEEPIDLE @=> tcp-keepidle #=> LONG
216 | CURLOPT_TCP_KEEPINTVL @=> tcp-keepintvl #=> LONG
217 | CURLOPT_SSL_OPTIONS @=> ssl-options #=> LONG
218 | CURLOPT_SASL_IR @=> sasl-ir #=> LONG
219 | CURLOPT_SSL_ENABLE_NPN @=> ssl-enable-npn #=> LONG
220 | CURLOPT_SSL_ENABLE_ALPN @=> ssl-enable-alpn #=> LONG
221 | CURLOPT_EXPECT_100_TIMEOUT_MS @=> expect-100-timeout-ms #=> LONG
222 | CURLOPT_HEADEROPT @=> headeropt #=> LONG
223 | CURLOPT_SSL_VERIFYSTATUS @=> ssl-verifystatus #=> LONG
224 | CURLOPT_SSL_FALSESTART @=> ssl-falsestart #=> LONG
225 | CURLOPT_PATH_AS_IS @=> path-as-is #=> LONG
226 | CURLOPT_PIPEWAIT @=> pipewait #=> LONG
227 | CURLOPT_STREAM_WEIGHT @=> stream-weight #=> LONG
228 | CURLOPT_TFTP_NO_OPTIONS @=> tftp-no-options #=> LONG
229 | CURLOPT_TCP_FASTOPEN @=> tcp-fastopen #=> LONG
230 | CURLOPT_KEEP_SENDING_ON_ERROR @=> keep-sending-on-error #=> LONG
231 | CURLOPT_PROXY_SSL_VERIFYPEER @=> proxy-ssl-verifypeer #=> LONG
232 | CURLOPT_PROXY_SSL_VERIFYHOST @=> proxy-ssl-verifyhost #=> LONG
233 | CURLOPT_PROXY_SSLVERSION @=> proxy-sslversion #=> LONG
234 | CURLOPT_PROXY_SSL_OPTIONS @=> proxy-ssl-options #=> LONG
235 | CURLOPT_SUPPRESS_CONNECT_HEADERS @=> suppress-connect-headers #=> LONG
236 | CURLOPT_SOCKS5_AUTH @=> socks5-auth #=> LONG
237 | CURLOPT_SSH_COMPRESSION @=> ssh-compression #=> LONG
238 | CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS @=> happy-eyeballs-timeout-ms #=> LONG
239 | CURLOPT_HAPROXYPROTOCOL @=> haproxyprotocol #=> LONG
240 | CURLOPT_DNS_SHUFFLE_ADDRESSES @=> dns-shuffle-addresses #=> LONG
241 | CURLOPT_DISALLOW_USERNAME_IN_URL @=> disallow-username-in-url #=> LONG
242 | CURLOPT_UPLOAD_BUFFERSIZE @=> upload-buffersize #=> LONG
243 | CURLOPT_UPKEEP_INTERVAL_MS @=> upkeep-interval-ms #=> LONG
244 | CURLOPT_HTTP09_ALLOWED @=> http09-allowed #=> LONG
245 |
246 | :=:
247 |
248 | CURLOPT_WRITEFUNCTION @=> writefunction #=> FUNCTIONPOINT
249 | CURLOPT_READFUNCTION @=> readfunction #=> FUNCTIONPOINT
250 | CURLOPT_PROGRESSFUNCTION @=> progressfunction #=> FUNCTIONPOINT
251 | CURLOPT_HEADERFUNCTION @=> headerfunction #=> FUNCTIONPOINT
252 | CURLOPT_DEBUGFUNCTION @=> debugfunction #=> FUNCTIONPOINT
253 | CURLOPT_SSL_CTX_FUNCTION @=> ssl-ctx-function #=> FUNCTIONPOINT
254 | CURLOPT_IOCTLFUNCTION @=> ioctlfunction #=> FUNCTIONPOINT
255 | CURLOPT_CONV_FROM_NETWORK_FUNCTION @=> conv-from-network-function #=> FUNCTIONPOINT
256 | CURLOPT_CONV_TO_NETWORK_FUNCTION @=> conv-to-network-function #=> FUNCTIONPOINT
257 | CURLOPT_CONV_FROM_UTF8_FUNCTION @=> conv-from-utf8-function #=> FUNCTIONPOINT
258 | CURLOPT_SOCKOPTFUNCTION @=> sockoptfunction #=> FUNCTIONPOINT
259 | CURLOPT_OPENSOCKETFUNCTION @=> opensocketfunction #=> FUNCTIONPOINT
260 | CURLOPT_SEEKFUNCTION @=> seekfunction #=> FUNCTIONPOINT
261 | CURLOPT_SSH_KEYFUNCTION @=> ssh-keyfunction #=> FUNCTIONPOINT
262 | CURLOPT_INTERLEAVEFUNCTION @=> interleavefunction #=> FUNCTIONPOINT
263 | CURLOPT_CHUNK_BGN_FUNCTION @=> chunk-bgn-function #=> FUNCTIONPOINT
264 | CURLOPT_CHUNK_END_FUNCTION @=> chunk-end-function #=> FUNCTIONPOINT
265 | CURLOPT_FNMATCH_FUNCTION @=> fnmatch-function #=> FUNCTIONPOINT
266 | CURLOPT_CLOSESOCKETFUNCTION @=> closesocketfunction #=> FUNCTIONPOINT
267 | CURLOPT_XFERINFOFUNCTION @=> xferinfofunction #=> FUNCTIONPOINT
268 | CURLOPT_RESOLVER_START_FUNCTION @=> resolver-start-function #=> FUNCTIONPOINT
269 | CURLOPT_TRAILERFUNCTION @=> trailerfunction #=> FUNCTIONPOINT
270 |
271 | :=:
272 |
273 | CURLOPT_INFILESIZE_LARGE @=> infilesize-large #=> OFF_T
274 | CURLOPT_RESUME_FROM_LARGE @=> resume-from-large #=> OFF_T
275 | CURLOPT_MAXFILESIZE_LARGE @=> maxfilesize-large #=> OFF_T
276 | CURLOPT_POSTFIELDSIZE_LARGE @=> postfieldsize-large #=> OFF_T
277 | CURLOPT_MAX_SEND_SPEED_LARGE @=> max-send-speed-large #=> OFF_T
278 | CURLOPT_MAX_RECV_SPEED_LARGE @=> max-recv-speed-large #=> OFF_T
279 | CURLOPT_TIMEVALUE_LARGE @=> timevalue-large #=> OFF_T
--------------------------------------------------------------------------------
/project.janet:
--------------------------------------------------------------------------------
1 | (declare-project
2 | :name "jurl"
3 | :description "Janet wrapper around libcurl"
4 | :author "Sepehr Aryani"
5 | :license "GPLv3"
6 | :url "https://github.com/sepisoad/jurl"
7 | :repo "https://github.com/sepisoad/jurl")
8 |
9 | (def lflags (case (os/which)
10 | :windows @["libcurl.lib"]
11 | :linux @["-lcurl"]
12 | #default
13 | @["-lcurl"]))
14 |
15 | (declare-native
16 | :name "curl"
17 | :lflags lflags
18 | :source ["src/curl.c"])
19 |
--------------------------------------------------------------------------------
/src/curl.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "khash.h"
4 |
5 | //==============================================================================
6 | // ██████╗ ██████╗ ███╗ ██╗███████╗████████╗ █████╗ ███╗ ██╗████████╗███████╗
7 | // ██╔════╝██╔═══██╗████╗ ██║██╔════╝╚══██╔══╝██╔══██╗████╗ ██║╚══██╔══╝██╔════╝
8 | // ██║ ██║ ██║██╔██╗ ██║███████╗ ██║ ███████║██╔██╗ ██║ ██║ ███████╗
9 | // ██║ ██║ ██║██║╚██╗██║╚════██║ ██║ ██╔══██║██║╚██╗██║ ██║ ╚════██║
10 | // ╚██████╗╚██████╔╝██║ ╚████║███████║ ██║ ██║ ██║██║ ╚████║ ██║ ███████║
11 | // ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚══════╝
12 | //==============================================================================
13 |
14 | #define DEFAULT_EASY_RECV_BUF_LEN 2014
15 |
16 | //==============================================================================
17 | // ████████╗██╗ ██╗██████╗ ███████╗███████╗
18 | // ╚══██╔══╝╚██╗ ██╔╝██╔══██╗██╔════╝██╔════╝
19 | // ██║ ╚████╔╝ ██████╔╝█████╗ ███████╗
20 | // ██║ ╚██╔╝ ██╔═══╝ ██╔══╝ ╚════██║
21 | // ██║ ██║ ██║ ███████╗███████║
22 | // ╚═╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝
23 | //==============================================================================
24 |
25 | typedef struct MapCurlOptionToJanetType MapCurlOptionToJanetType;
26 | typedef struct MapCurlInfoToJanetType MapCurlInfoToJanetType;
27 | typedef struct Curl Curl;
28 | typedef struct Curlsh Curlsh;
29 | typedef struct Url Url;
30 | typedef struct Mime Mime;
31 | typedef struct MimePart MimePart; // does not need GC, it gets freed when Mime parent object GC happens
32 |
33 | struct MapCurlOptionToJanetType {
34 | int option;
35 | JanetType type;
36 | };
37 |
38 | struct MapCurlInfoToJanetType {
39 | int info;
40 | JanetType type;
41 | };
42 |
43 | struct Curl {
44 | CURL *curl;
45 | JanetFunction *write_function;
46 | JanetFunction *header_function;
47 | JanetFunction *read_function;
48 | JanetFunction *progress_function;
49 | };
50 |
51 | struct Curlsh {
52 | CURLSH *curlsh;
53 | };
54 |
55 | struct Url {
56 | CURLU *url;
57 | };
58 |
59 | struct Mime {
60 | curl_mime *mime;
61 | };
62 |
63 | struct MimePart {
64 | curl_mimepart *mimepart;
65 | };
66 |
67 | //==============================================================================
68 | // ██████╗ ██████╗ ██████╗ ████████╗ ██████╗ ████████╗██╗ ██╗██████╗ ███████╗███████╗
69 | // ██╔══██╗██╔══██╗██╔═══██╗╚══██╔══╝██╔═══██╗╚══██╔══╝╚██╗ ██╔╝██╔══██╗██╔════╝██╔════╝
70 | // ██████╔╝██████╔╝██║ ██║ ██║ ██║ ██║ ██║ ╚████╔╝ ██████╔╝█████╗ ███████╗
71 | // ██╔═══╝ ██╔══██╗██║ ██║ ██║ ██║ ██║ ██║ ╚██╔╝ ██╔═══╝ ██╔══╝ ╚════██║
72 | // ██║ ██║ ██║╚██████╔╝ ██║ ╚██████╔╝ ██║ ██║ ██║ ███████╗███████║
73 | // ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝
74 | //==============================================================================
75 |
76 | static int curl_gc_fn(void *data, size_t len);
77 | static int curl_get_fn(void *data, Janet key, Janet *out);
78 | static Janet easy_init(int32_t argc, Janet *argv);
79 | static Janet easy_clone(int32_t argc, Janet *argv);
80 | static Janet easy_escape(int32_t argc, Janet *argv);
81 | static Janet easy_unescape(int32_t argc, Janet *argv);
82 | static Janet easy_strerror(int32_t argc, Janet *argv);
83 | static Janet easy_setopt(int32_t argc, Janet *argv);
84 | static Janet easy_pause(int32_t argc, Janet *argv);
85 | static Janet easy_reset(int32_t argc, Janet *argv);
86 | static Janet easy_upkeep(int32_t argc, Janet *argv);
87 | static Janet easy_recv(int32_t argc, Janet *argv);
88 | static Janet easy_send(int32_t argc, Janet *argv);
89 | static Janet easy_perform(int32_t argc, Janet *argv);
90 | static Janet easy_query(int32_t argc, Janet *argv);
91 |
92 | static int curlsh_gc_fn(void *data, size_t len);
93 | static int curl_mark_fn(void *data, size_t len);
94 | static int curlsh_get_fn(void *data, Janet key, Janet *out);
95 | static Janet share_init(int32_t argc, Janet *argv);
96 | static Janet share_setopt(int32_t argc, Janet *argv);
97 | static Janet share_strerror(int32_t argc, Janet *argv);
98 |
99 | static int url_gc_fn(void *data, size_t len);
100 | static int url_get_fn(void *data, Janet key, Janet *out);
101 | static Janet url_init(int32_t argc, Janet *argv);
102 | static Janet url_clone(int32_t argc, Janet *argv);
103 | static Janet url_get(int32_t argc, Janet *argv);
104 | static Janet url_set(int32_t argc, Janet *argv);
105 |
106 | static int mime_gc_fn(void *data, size_t len);
107 | static int mime_get_fn(void *data, Janet key, Janet *out);
108 | static Janet mime_init(int32_t argc, Janet *argv);
109 |
110 | //==============================================================================
111 | // ██████╗ ██╗ ██████╗ ██████╗ █████╗ ██╗ ███████╗
112 | // ██╔════╝ ██║ ██╔═══██╗██╔══██╗██╔══██╗██║ ██╔════╝
113 | // ██║ ███╗██║ ██║ ██║██████╔╝███████║██║ ███████╗
114 | // ██║ ██║██║ ██║ ██║██╔══██╗██╔══██║██║ ╚════██║
115 | // ╚██████╔╝███████╗╚██████╔╝██████╔╝██║ ██║███████╗███████║
116 | // ╚═════╝ ╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝
117 | //==============================================================================
118 |
119 | KHASH_MAP_INIT_STR(HashMapCurlOptionToJanetType, MapCurlOptionToJanetType *);
120 | khash_t(HashMapCurlOptionToJanetType) *hashmap_opt_to_type = NULL;
121 |
122 | KHASH_MAP_INIT_STR(HashMapCurlInfoToJanetType, MapCurlInfoToJanetType *);
123 | khash_t(HashMapCurlInfoToJanetType) *hashmap_info_to_type = NULL;
124 |
125 | JanetAbstractType curl_obj = {"curl", curl_gc_fn, curl_mark_fn, curl_get_fn, JANET_ATEND_GET};
126 | JanetAbstractType curlsh_obj = {"curlsh", curlsh_gc_fn, NULL, curlsh_get_fn, JANET_ATEND_GET};
127 | JanetAbstractType url_obj = {"url", url_gc_fn, NULL, url_get_fn, JANET_ATEND_GET};
128 | JanetAbstractType mime_obj = {"mime", mime_gc_fn, NULL, mime_get_fn, JANET_ATEND_GET};
129 | JanetAbstractType mimepart_obj = {"mimepart", JANET_ATEND_NAME};
130 |
131 | static JanetMethod curl_methods[] = {
132 | {"clone", easy_clone},
133 | {"escape", easy_escape},
134 | {"unescape", easy_unescape},
135 | {"setopt", easy_setopt},
136 | {"pause", easy_pause},
137 | {"reset", easy_reset},
138 | {"upkeep", easy_upkeep},
139 | {"recv", easy_recv},
140 | {"send", easy_send},
141 | {"perform", easy_perform},
142 | {"query", easy_query},
143 | {NULL, NULL}
144 | };
145 |
146 | static JanetMethod curlsh_methods[] = {
147 | {"setopt", easy_setopt},
148 | {NULL, NULL}
149 | };
150 |
151 | static JanetMethod url_methods[] = {
152 | {"clone", url_clone},
153 | {"get", url_get},
154 | {"set", url_set},
155 | {NULL, NULL}
156 | };
157 |
158 | static JanetMethod mime_methods[] = { // FIXME:
159 | {NULL, NULL}
160 | };
161 |
162 | //==============================================================================
163 | // ██████╗ █████╗ ███████╗███████╗
164 | // ██╔══██╗██╔══██╗██╔════╝██╔════╝
165 | // ██████╔╝███████║███████╗█████╗
166 | // ██╔══██╗██╔══██║╚════██║██╔══╝
167 | // ██████╔╝██║ ██║███████║███████╗
168 | // ╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝
169 | //==============================================================================
170 |
171 | static Janet curl_make(CURL *curl) {
172 | Curl *c = (Curl *) janet_abstract(&curl_obj, sizeof(Curl));
173 | memset(c, 0, sizeof(Curl));
174 | c->curl = curl;
175 | return janet_wrap_abstract(c);
176 | }
177 |
178 | static int curl_gc_fn(void *data, size_t len) {
179 | (void) len;
180 |
181 | Curl *c = (Curl *)data;
182 | curl_easy_cleanup(c->curl);
183 |
184 | return 0;
185 | }
186 |
187 | static int curl_mark_fn(void *data, size_t len) {
188 | (void) len;
189 |
190 | Curl *c = (Curl *)data;
191 | if (c->read_function) janet_mark(janet_wrap_function(c->read_function));
192 | if (c->write_function) janet_mark(janet_wrap_function(c->write_function));
193 | if (c->progress_function) janet_mark(janet_wrap_function(c->progress_function));
194 | if (c->header_function) janet_mark(janet_wrap_function(c->header_function));
195 | return 0;
196 | }
197 |
198 | static int curl_get_fn(void *data, Janet key, Janet *out) {
199 | (void) data;
200 |
201 | if (!janet_checktype(key, JANET_KEYWORD))
202 | janet_panicf("expected keyword, got %v", key);
203 | return janet_getmethod(janet_unwrap_keyword(key), curl_methods, out);
204 | }
205 |
206 | static Janet curlsh_make(CURLSH *curlsh) {
207 | Curlsh *c = (Curlsh *) janet_abstract(&curl_obj, sizeof(Curlsh));
208 | c->curlsh = curlsh;
209 | return janet_wrap_abstract(c);
210 | }
211 |
212 | static int curlsh_gc_fn(void *data, size_t len) {
213 | (void) len;
214 |
215 | Curlsh *c = (Curlsh *)data;
216 | curl_share_cleanup(c->curlsh);
217 |
218 | return 0;
219 | }
220 |
221 | static int curlsh_get_fn(void *data, Janet key, Janet *out) {
222 | (void) data;
223 |
224 | if (!janet_checktype(key, JANET_KEYWORD))
225 | janet_panicf("expected keyword, got %v", key);
226 | return janet_getmethod(janet_unwrap_keyword(key), curlsh_methods, out);
227 | }
228 |
229 | static Janet url_make(CURLU *url) {
230 | Url *u = (Url *) janet_abstract(&url_obj, sizeof(Url));
231 | u->url = url;
232 | return janet_wrap_abstract(u);
233 | }
234 |
235 | static int url_gc_fn(void *data, size_t len) {
236 | (void) len;
237 |
238 | Url *u = (Url *)data;
239 | curl_url_cleanup(u->url);
240 |
241 | return 0;
242 | }
243 |
244 | static int url_get_fn(void *data, Janet key, Janet *out) {
245 | (void) data;
246 |
247 | if (!janet_checktype(key, JANET_KEYWORD))
248 | janet_panicf("expected keyword, got %v", key);
249 | return janet_getmethod(janet_unwrap_keyword(key), url_methods, out);
250 | }
251 |
252 | static Janet mime_make(curl_mime *mime) {
253 | Mime *m = (Mime *) janet_abstract(&mime_obj, sizeof(Mime));
254 | m->mime = mime;
255 | return janet_wrap_abstract(m);
256 | }
257 |
258 | static int mime_gc_fn(void *data, size_t len) {
259 | (void) len;
260 |
261 | Mime *m = (Mime *)data;
262 | curl_mime_free(m->mime);
263 |
264 | return 0;
265 | }
266 |
267 | static int mime_get_fn(void *data, Janet key, Janet *out) {
268 | (void) data;
269 |
270 | if (!janet_checktype(key, JANET_KEYWORD))
271 | janet_panicf("expected keyword, got %v", key);
272 | return janet_getmethod(janet_unwrap_keyword(key), mime_methods, out);
273 | }
274 |
275 | static Janet mimepart_make(curl_mimepart *mimepart) {
276 | MimePart *mp = (MimePart *) janet_abstract(&mimepart_obj, sizeof(MimePart));
277 | mp->mimepart = mimepart;
278 | return janet_wrap_abstract(mp);
279 | }
280 |
281 | //==============================================================================
282 | // ██████╗ █████╗ ██╗ ██╗ ██████╗ █████╗ ██████╗██╗ ██╗███████╗
283 | // ██╔════╝██╔══██╗██║ ██║ ██╔══██╗██╔══██╗██╔════╝██║ ██╔╝██╔════╝
284 | // ██║ ███████║██║ ██║ ██████╔╝███████║██║ █████╔╝ ███████╗
285 | // ██║ ██╔══██║██║ ██║ ██╔══██╗██╔══██║██║ ██╔═██╗ ╚════██║
286 | // ╚██████╗██║ ██║███████╗███████╗██████╔╝██║ ██║╚██████╗██║ ██╗███████║
287 | // ╚═════╝╚═╝ ╚═╝╚══════╝╚══════╝╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝
288 | //==============================================================================
289 |
290 | static size_t funcs_write(void *buff, size_t size, size_t count, void *udata) {
291 | const size_t len = size * count;
292 |
293 | if (len > 0 && buff != NULL) {
294 | JanetBuffer *jbuff = janet_buffer(len);
295 | janet_buffer_push_bytes(jbuff, buff, len);
296 | Janet arg = janet_wrap_buffer(jbuff);
297 |
298 | JanetFunction *jfunc = (JanetFunction *)udata;
299 | janet_call(jfunc, 1, &arg);
300 | }
301 |
302 | return len;
303 | }
304 |
305 | static size_t funcs_read(char *buff, size_t size, size_t count, void *udata) {
306 | Janet len = janet_wrap_number(size * count);
307 | JanetFunction *jfunc = (JanetFunction *)udata;
308 | Janet jbuff = janet_call(jfunc, 1, &len);
309 | JanetByteView bytes = janet_getbytes(&jbuff, 0);
310 | if ((size_t) bytes.len > size) bytes.len = (int32_t) size;
311 | memcpy(buff, bytes.bytes, bytes.len);
312 | return (size_t) bytes.len;
313 | }
314 |
315 | static int funcs_progress(void *udata, double dltotal, double dlnow, double ultotal, double ulnow) {
316 | JanetFunction *jfunc = (JanetFunction *)udata;
317 | Janet args[4];
318 | args[0] = janet_wrap_number(dltotal);
319 | args[1] = janet_wrap_number(dlnow);
320 | args[2] = janet_wrap_number(ultotal);
321 | args[3] = janet_wrap_number(ulnow);
322 |
323 | Janet res = janet_call(jfunc, 4, args);
324 |
325 | return janet_truthy(res);
326 | }
327 |
328 | // static size_t funcs_mime_mem_read(char *buffer, size_t size, size_t nitems, void *instream)
329 | // {
330 | // curl_mimepart *part = (curl_mimepart *) instream;
331 | // size_t sz = (size_t) part->datasize - part->state.offset;
332 | // (void) size; /* Always 1.*/
333 |
334 | // if(sz > nitems)
335 | // sz = nitems;
336 |
337 | // if(sz)
338 | // memcpy(buffer, (char *) &part->data[part->state.offset], sz);
339 |
340 | // part->state.offset += sz;
341 | // return sz;
342 | // }
343 |
344 | // static int funcs_mime_mem_seek(void *instream, curl_off_t offset, int whence)
345 | // {
346 | // curl_mimepart *part = (curl_mimepart *) instream;
347 |
348 | // switch(whence) {
349 | // case SEEK_CUR:
350 | // offset += part->state.offset;
351 | // break;
352 | // case SEEK_END:
353 | // offset += part->datasize;
354 | // break;
355 | // }
356 |
357 | // if(offset < 0 || offset > part->datasize)
358 | // return CURL_SEEKFUNC_FAIL;
359 |
360 | // part->state.offset = (size_t) offset;
361 | // return CURL_SEEKFUNC_OK;
362 | // }
363 |
364 | // static void funcs_mime_mem_free(void *ptr)
365 | // {
366 | // Curl_safefree(((curl_mimepart *) ptr)->data);
367 | // }
368 |
369 |
370 | //==============================================================================
371 | // ██████╗ ██████╗ ████████╗██╗ ██████╗ ███╗ ██╗███████╗
372 | // ██╔═══██╗██╔══██╗╚══██╔══╝██║██╔═══██╗████╗ ██║██╔════╝
373 | // ██║ ██║██████╔╝ ██║ ██║██║ ██║██╔██╗ ██║███████╗
374 | // ██║ ██║██╔═══╝ ██║ ██║██║ ██║██║╚██╗██║╚════██║
375 | // ╚██████╔╝██║ ██║ ██║╚██████╔╝██║ ╚████║███████║
376 | // ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝╚══════╝
377 | //==============================================================================
378 |
379 | static struct {
380 | char name[64];
381 | MapCurlOptionToJanetType kjm;
382 | } _key_option_type_arr[] = {
383 | {"url", {CURLOPT_URL, JANET_STRING}},
384 | {"proxy", {CURLOPT_PROXY, JANET_STRING}},
385 | {"user-password", {CURLOPT_USERPWD, JANET_STRING}},
386 | {"proxy-username-password", {CURLOPT_PROXYUSERPWD, JANET_STRING}},
387 | {"range", {CURLOPT_RANGE, JANET_STRING}},
388 | {"referer", {CURLOPT_REFERER, JANET_STRING}},
389 | {"ftp-port", {CURLOPT_FTPPORT, JANET_STRING}},
390 | {"user-agent", {CURLOPT_USERAGENT, JANET_STRING}},
391 | {"cookie", {CURLOPT_COOKIE, JANET_STRING}},
392 | {"ssl-cert", {CURLOPT_SSLCERT, JANET_STRING}},
393 | {"key-pass", {CURLOPT_KEYPASSWD, JANET_STRING}},
394 | {"cookie-file", {CURLOPT_COOKIEFILE, JANET_STRING}},
395 | {"custom-request", {CURLOPT_CUSTOMREQUEST, JANET_STRING}},
396 | {"interface", {CURLOPT_INTERFACE, JANET_STRING}},
397 | {"krb-level", {CURLOPT_KRBLEVEL, JANET_STRING}},
398 | {"ca-info", {CURLOPT_CAINFO, JANET_STRING}},
399 | {"random-file", {CURLOPT_RANDOM_FILE, JANET_STRING}},
400 | {"egd-socket", {CURLOPT_EGDSOCKET, JANET_STRING}},
401 | {"cookie-jar", {CURLOPT_COOKIEJAR, JANET_STRING}},
402 | {"ssl-cipher-list", {CURLOPT_SSL_CIPHER_LIST, JANET_STRING}},
403 | {"ssl-cert-type", {CURLOPT_SSLCERTTYPE, JANET_STRING}},
404 | {"ssl-key", {CURLOPT_SSLKEY, JANET_STRING}},
405 | {"ssl-key-type", {CURLOPT_SSLKEYTYPE, JANET_STRING}},
406 | {"ssl-engine", {CURLOPT_SSLENGINE, JANET_STRING}},
407 | {"ca-path", {CURLOPT_CAPATH, JANET_STRING}},
408 | {"accept-encoding", {CURLOPT_ACCEPT_ENCODING, JANET_STRING}},
409 | {"net-rc-file", {CURLOPT_NETRC_FILE, JANET_STRING}},
410 | {"ftp-account", {CURLOPT_FTP_ACCOUNT, JANET_STRING}},
411 | {"cookie-list", {CURLOPT_COOKIELIST, JANET_STRING}},
412 | {"ftp-alternative-to-user", {CURLOPT_FTP_ALTERNATIVE_TO_USER, JANET_STRING}},
413 | {"ssh-public-key-file", {CURLOPT_SSH_PUBLIC_KEYFILE, JANET_STRING}},
414 | {"ssh-private-key-file", {CURLOPT_SSH_PRIVATE_KEYFILE, JANET_STRING}},
415 | {"ssh-host-public-key-md5", {CURLOPT_SSH_HOST_PUBLIC_KEY_MD5, JANET_STRING}},
416 | {"crl-file", {CURLOPT_CRLFILE, JANET_STRING}},
417 | {"issuer-cert", {CURLOPT_ISSUERCERT, JANET_STRING}},
418 | {"username", {CURLOPT_USERNAME, JANET_STRING}},
419 | {"password", {CURLOPT_PASSWORD, JANET_STRING}},
420 | {"proxy-username", {CURLOPT_PROXYUSERNAME, JANET_STRING}},
421 | {"proxy-password", {CURLOPT_PROXYPASSWORD, JANET_STRING}},
422 | {"no-proxy", {CURLOPT_NOPROXY, JANET_STRING}},
423 | {"socks5-gss-api-service", {CURLOPT_SOCKS5_GSSAPI_SERVICE, JANET_STRING}},
424 | {"ssh-known-hosts", {CURLOPT_SSH_KNOWNHOSTS, JANET_STRING}},
425 | {"mail-from", {CURLOPT_MAIL_FROM, JANET_STRING}},
426 | {"rtsp-session-id", {CURLOPT_RTSP_SESSION_ID, JANET_STRING}},
427 | {"rtsp-stream-uri", {CURLOPT_RTSP_STREAM_URI, JANET_STRING}},
428 | {"rtsp-transport", {CURLOPT_RTSP_TRANSPORT, JANET_STRING}},
429 | {"tls-auth-username", {CURLOPT_TLSAUTH_USERNAME, JANET_STRING}},
430 | {"tls-auth-password", {CURLOPT_TLSAUTH_PASSWORD, JANET_STRING}},
431 | {"tls-auth-type", {CURLOPT_TLSAUTH_TYPE, JANET_STRING}},
432 | {"dns-servers", {CURLOPT_DNS_SERVERS, JANET_STRING}},
433 | {"mail-auth", {CURLOPT_MAIL_AUTH, JANET_STRING}},
434 | {"xoauth2-bearer", {CURLOPT_XOAUTH2_BEARER, JANET_STRING}},
435 | {"dns-interface", {CURLOPT_DNS_INTERFACE, JANET_STRING}},
436 | {"dns-local-ip4", {CURLOPT_DNS_LOCAL_IP4, JANET_STRING}},
437 | {"dns-local-ip6", {CURLOPT_DNS_LOCAL_IP6, JANET_STRING}},
438 | {"login-options", {CURLOPT_LOGIN_OPTIONS, JANET_STRING}},
439 | {"pinned-public-key", {CURLOPT_PINNEDPUBLICKEY, JANET_STRING}},
440 | {"unix-socket-path", {CURLOPT_UNIX_SOCKET_PATH, JANET_STRING}},
441 | {"proxy-service-name", {CURLOPT_PROXY_SERVICE_NAME, JANET_STRING}},
442 | {"service-name", {CURLOPT_SERVICE_NAME, JANET_STRING}},
443 | {"default-protocol", {CURLOPT_DEFAULT_PROTOCOL, JANET_STRING}},
444 | {"proxy-ca-info", {CURLOPT_PROXY_CAINFO, JANET_STRING}},
445 | {"proxy-ca-path", {CURLOPT_PROXY_CAPATH, JANET_STRING}},
446 | {"proxy-tls-auth-username", {CURLOPT_PROXY_TLSAUTH_USERNAME, JANET_STRING}},
447 | {"proxy-tls-auth-password", {CURLOPT_PROXY_TLSAUTH_PASSWORD, JANET_STRING}},
448 | {"proxy-tls-auth-type", {CURLOPT_PROXY_TLSAUTH_TYPE, JANET_STRING}},
449 | {"proxy-ssl-cert", {CURLOPT_PROXY_SSLCERT, JANET_STRING}},
450 | {"proxy-ssl-cert-type", {CURLOPT_PROXY_SSLCERTTYPE, JANET_STRING}},
451 | {"proxy-ssl-key", {CURLOPT_PROXY_SSLKEY, JANET_STRING}},
452 | {"proxy-ssl-key-type", {CURLOPT_PROXY_SSLKEYTYPE, JANET_STRING}},
453 | {"proxy-key-password", {CURLOPT_PROXY_KEYPASSWD, JANET_STRING}},
454 | {"proxy-ssl-cipher-list", {CURLOPT_PROXY_SSL_CIPHER_LIST, JANET_STRING}},
455 | {"proxy-crl-file", {CURLOPT_PROXY_CRLFILE, JANET_STRING}},
456 | {"pre-proxy", {CURLOPT_PRE_PROXY, JANET_STRING}},
457 | {"proxy-pinned-public-key", {CURLOPT_PROXY_PINNEDPUBLICKEY, JANET_STRING}},
458 | {"abstract-unix-socket", {CURLOPT_ABSTRACT_UNIX_SOCKET, JANET_STRING}},
459 | {"request-target", {CURLOPT_REQUEST_TARGET, JANET_STRING}},
460 | {"tls13-ciphers", {CURLOPT_TLS13_CIPHERS, JANET_STRING}},
461 | {"proxy-tls13-ciphers", {CURLOPT_PROXY_TLS13_CIPHERS, JANET_STRING}},
462 | {"doh-url", {CURLOPT_DOH_URL, JANET_STRING}},
463 | {"aws-sigv4", {CURLOPT_AWS_SIGV4, JANET_STRING}},
464 | {"copy-post-fields", {CURLOPT_COPYPOSTFIELDS, JANET_STRING}},
465 |
466 | {"verbose?", {CURLOPT_VERBOSE, JANET_BOOLEAN}},
467 | {"header?", {CURLOPT_HEADER, JANET_BOOLEAN}},
468 | {"no-progress?", {CURLOPT_NOPROGRESS, JANET_BOOLEAN}},
469 | {"no-body?", {CURLOPT_NOBODY, JANET_BOOLEAN}},
470 | {"fail-on-error?", {CURLOPT_FAILONERROR, JANET_BOOLEAN}},
471 | {"upload?", {CURLOPT_UPLOAD, JANET_BOOLEAN}},
472 | {"post?", {CURLOPT_POST, JANET_BOOLEAN}},
473 | {"dir-list-only?", {CURLOPT_DIRLISTONLY, JANET_BOOLEAN}},
474 | {"append?", {CURLOPT_APPEND, JANET_BOOLEAN}},
475 | {"follow-location?", {CURLOPT_FOLLOWLOCATION, JANET_BOOLEAN}},
476 | {"transfer-text?", {CURLOPT_TRANSFERTEXT, JANET_BOOLEAN}},
477 | {"put?", {CURLOPT_PUT, JANET_BOOLEAN}},
478 | {"auto-referer?", {CURLOPT_AUTOREFERER, JANET_BOOLEAN}},
479 | {"http-proxy-tunnel?", {CURLOPT_HTTPPROXYTUNNEL, JANET_BOOLEAN}},
480 | {"ssl-verify-peer?", {CURLOPT_SSL_VERIFYPEER, JANET_BOOLEAN}},
481 | {"file-time?", {CURLOPT_FILETIME, JANET_BOOLEAN}},
482 | {"fresh-connect?", {CURLOPT_FRESH_CONNECT, JANET_BOOLEAN}},
483 | {"forbid-reuse?", {CURLOPT_FORBID_REUSE, JANET_BOOLEAN}},
484 | {"http-get?", {CURLOPT_HTTPGET, JANET_BOOLEAN}},
485 | {"ftp-use-epsv?", {CURLOPT_FTP_USE_EPSV, JANET_BOOLEAN}},
486 | {"ssl-engine-default?", {CURLOPT_SSLENGINE_DEFAULT, JANET_BOOLEAN}},
487 | {"dns-use-global-cache?", {CURLOPT_DNS_USE_GLOBAL_CACHE, JANET_BOOLEAN}},
488 | {"cookie-session?", {CURLOPT_COOKIESESSION, JANET_BOOLEAN}},
489 | {"no-signal?", {CURLOPT_NOSIGNAL, JANET_BOOLEAN}},
490 | {"unrestricted-auth?", {CURLOPT_UNRESTRICTED_AUTH, JANET_BOOLEAN}},
491 | {"ftp-use-eprt?", {CURLOPT_FTP_USE_EPRT, JANET_BOOLEAN}},
492 | {"tcp-no-delay?", {CURLOPT_TCP_NODELAY, JANET_BOOLEAN}},
493 | {"ignore-content-length?", {CURLOPT_IGNORE_CONTENT_LENGTH, JANET_BOOLEAN}},
494 | {"ftp-skip-pasv-ip?", {CURLOPT_FTP_SKIP_PASV_IP, JANET_BOOLEAN}},
495 | {"connect-only?", {CURLOPT_CONNECT_ONLY, JANET_BOOLEAN}},
496 | {"ssl-sessionid-cache?", {CURLOPT_SSL_SESSIONID_CACHE, JANET_BOOLEAN}},
497 | {"http-transfer-decoding?", {CURLOPT_HTTP_TRANSFER_DECODING, JANET_BOOLEAN}},
498 | {"http-content-decoding?", {CURLOPT_HTTP_CONTENT_DECODING, JANET_BOOLEAN}},
499 | {"proxy-transfer-mode?", {CURLOPT_PROXY_TRANSFER_MODE, JANET_BOOLEAN}},
500 | {"cert-info?", {CURLOPT_CERTINFO, JANET_BOOLEAN}},
501 | {"socks5-gss-api-nec?", {CURLOPT_SOCKS5_GSSAPI_NEC, JANET_BOOLEAN}},
502 | {"ftp-use-pret?", {CURLOPT_FTP_USE_PRET, JANET_BOOLEAN}},
503 | {"wildcard-match?", {CURLOPT_WILDCARDMATCH, JANET_BOOLEAN}},
504 | {"transfer-encoding?", {CURLOPT_TRANSFER_ENCODING, JANET_BOOLEAN}},
505 | {"sasl-ir?", {CURLOPT_SASL_IR, JANET_BOOLEAN}},
506 | {"ssl-enable-npn?", {CURLOPT_SSL_ENABLE_NPN, JANET_BOOLEAN}},
507 | {"ssl-enable-alpn?", {CURLOPT_SSL_ENABLE_ALPN, JANET_BOOLEAN}},
508 | {"ssl-verify-status?", {CURLOPT_SSL_VERIFYSTATUS, JANET_BOOLEAN}},
509 | {"ssl-false-start?", {CURLOPT_SSL_FALSESTART, JANET_BOOLEAN}},
510 | {"path-as-is?", {CURLOPT_PATH_AS_IS, JANET_BOOLEAN}},
511 | {"pipe-wait?", {CURLOPT_PIPEWAIT, JANET_BOOLEAN}},
512 | {"tftp-no-options?", {CURLOPT_TFTP_NO_OPTIONS, JANET_BOOLEAN}},
513 | {"tcp-fastopen?", {CURLOPT_TCP_FASTOPEN, JANET_BOOLEAN}},
514 | {"keep-sending-on-error?", {CURLOPT_KEEP_SENDING_ON_ERROR, JANET_BOOLEAN}},
515 | {"proxy-ssl-verify-peer?", {CURLOPT_PROXY_SSL_VERIFYPEER, JANET_BOOLEAN}},
516 | {"suppress-connect-headers?", {CURLOPT_SUPPRESS_CONNECT_HEADERS, JANET_BOOLEAN}},
517 | {"ssh-compression?", {CURLOPT_SSH_COMPRESSION, JANET_BOOLEAN}},
518 | {"ha-proxy-protocol?", {CURLOPT_HAPROXYPROTOCOL, JANET_BOOLEAN}},
519 | {"dns-shuffle-addresses?", {CURLOPT_DNS_SHUFFLE_ADDRESSES, JANET_BOOLEAN}},
520 | {"disallow-username-in-url?", {CURLOPT_DISALLOW_USERNAME_IN_URL, JANET_BOOLEAN}},
521 | {"http09-allowed?", {CURLOPT_HTTP09_ALLOWED, JANET_BOOLEAN}},
522 | {"ssl-verify-host?", {CURLOPT_SSL_VERIFYHOST, JANET_NUMBER}},
523 |
524 | // ENUMS
525 | {"proxy-type", {CURLOPT_PROXYTYPE, JANET_NUMBER}},
526 | {"ftp-create-missing-dirs", {CURLOPT_FTP_CREATE_MISSING_DIRS, JANET_NUMBER}},
527 | {"ip-resolve", {CURLOPT_IPRESOLVE, JANET_NUMBER}},
528 | {"use-ssl", {CURLOPT_USE_SSL, JANET_NUMBER}},
529 | {"ftp-ssl-auth", {CURLOPT_FTPSSLAUTH, JANET_NUMBER}},
530 | {"ftp-file-method", {CURLOPT_FTP_FILEMETHOD, JANET_NUMBER}},
531 | {"ftp-ssl-ccc", {CURLOPT_FTP_SSL_CCC, JANET_NUMBER}},
532 | {"rtsp-request", {CURLOPT_RTSP_REQUEST, JANET_NUMBER}},
533 | {"gss-api-delegation", {CURLOPT_GSSAPI_DELEGATION, JANET_NUMBER}},
534 | {"proxy-ssl-verify-host", {CURLOPT_PROXY_SSL_VERIFYHOST, JANET_NUMBER}},
535 | {"proxy-ssl-version", {CURLOPT_PROXY_SSLVERSION, JANET_NUMBER}},
536 | {"netrc", {CURLOPT_NETRC, JANET_NUMBER}},
537 |
538 | // MASKS
539 | {"ssh-auth-types", {CURLOPT_SSH_AUTH_TYPES, JANET_NUMBER}},
540 | {"post-redir", {CURLOPT_POSTREDIR, JANET_NUMBER}},
541 | {"protocols", {CURLOPT_PROTOCOLS, JANET_NUMBER}},
542 | {"redir-protocols", {CURLOPT_REDIR_PROTOCOLS, JANET_NUMBER}},
543 | {"ssl-options", {CURLOPT_SSL_OPTIONS, JANET_NUMBER}},
544 | {"header-opt", {CURLOPT_HEADEROPT, JANET_NUMBER}},
545 | {"proxy-ssl-options", {CURLOPT_PROXY_SSL_OPTIONS, JANET_NUMBER}},
546 | {"http-auth", {CURLOPT_HTTPAUTH, JANET_NUMBER}},
547 | {"proxy-auth", {CURLOPT_PROXYAUTH, JANET_NUMBER}},
548 | {"socks5-auth", {CURLOPT_SOCKS5_AUTH, JANET_NUMBER}},
549 |
550 | {"port", {CURLOPT_PORT, JANET_NUMBER}},
551 | {"timeout", {CURLOPT_TIMEOUT, JANET_NUMBER}},
552 | {"infilesize", {CURLOPT_INFILESIZE, JANET_NUMBER}},
553 | {"low-speed-limit", {CURLOPT_LOW_SPEED_LIMIT, JANET_NUMBER}},
554 | {"low-speed-time", {CURLOPT_LOW_SPEED_TIME, JANET_NUMBER}},
555 | {"resume-from", {CURLOPT_RESUME_FROM, JANET_NUMBER}},
556 | {"crlf", {CURLOPT_CRLF, JANET_NUMBER}},
557 | {"ssl-version", {CURLOPT_SSLVERSION, JANET_NUMBER}},
558 | {"time-condition", {CURLOPT_TIMECONDITION, JANET_NUMBER}},
559 | {"time-value", {CURLOPT_TIMEVALUE, JANET_NUMBER}},
560 | {"proxy-port", {CURLOPT_PROXYPORT, JANET_NUMBER}},
561 | {"post-field-size", {CURLOPT_POSTFIELDSIZE, JANET_NUMBER}},
562 | {"post-fields", {CURLOPT_POSTFIELDS, JANET_POINTER}},
563 | {"max-redirs", {CURLOPT_MAXREDIRS, JANET_NUMBER}},
564 | {"max-connects", {CURLOPT_MAXCONNECTS, JANET_NUMBER}},
565 | {"obsolete72", {CURLOPT_OBSOLETE72, JANET_NUMBER}},
566 | {"connect-timeout", {CURLOPT_CONNECTTIMEOUT, JANET_NUMBER}},
567 | {"http-version", {CURLOPT_HTTP_VERSION, JANET_NUMBER}},
568 | {"dns-cache-timeout", {CURLOPT_DNS_CACHE_TIMEOUT, JANET_NUMBER}},
569 | {"buffer-size", {CURLOPT_BUFFERSIZE, JANET_NUMBER}},
570 | {"ftp-response-timeout", {CURLOPT_FTP_RESPONSE_TIMEOUT, JANET_NUMBER}},
571 | {"max-filesize", {CURLOPT_MAXFILESIZE, JANET_NUMBER}},
572 | {"local-port", {CURLOPT_LOCALPORT, JANET_NUMBER}},
573 | {"local-portrange", {CURLOPT_LOCALPORTRANGE, JANET_NUMBER}},
574 | {"timeout-ms", {CURLOPT_TIMEOUT_MS, JANET_NUMBER}},
575 | {"connect-timeout-ms", {CURLOPT_CONNECTTIMEOUT_MS, JANET_NUMBER}},
576 | {"new-file-perms", {CURLOPT_NEW_FILE_PERMS, JANET_NUMBER}},
577 | {"new-directory-perms", {CURLOPT_NEW_DIRECTORY_PERMS, JANET_NUMBER}},
578 | {"address-scope", {CURLOPT_ADDRESS_SCOPE, JANET_NUMBER}},
579 | {"tftp-blk-size", {CURLOPT_TFTP_BLKSIZE, JANET_NUMBER}},
580 | {"rtsp-client-cseq", {CURLOPT_RTSP_CLIENT_CSEQ, JANET_NUMBER}},
581 | {"rtsp-server-cseq", {CURLOPT_RTSP_SERVER_CSEQ, JANET_NUMBER}},
582 | {"accept-timeout-ms", {CURLOPT_ACCEPTTIMEOUT_MS, JANET_NUMBER}},
583 | {"tcp-keep-alive", {CURLOPT_TCP_KEEPALIVE, JANET_NUMBER}},
584 | {"tcp-keep-idle", {CURLOPT_TCP_KEEPIDLE, JANET_NUMBER}},
585 | {"tcp-keep-intvl", {CURLOPT_TCP_KEEPINTVL, JANET_NUMBER}},
586 | {"expect-100-timeout-ms", {CURLOPT_EXPECT_100_TIMEOUT_MS, JANET_NUMBER}},
587 | {"stream-weight", {CURLOPT_STREAM_WEIGHT, JANET_NUMBER}},
588 | {"happy-eyeballs-timeout-ms", {CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS, JANET_NUMBER}},
589 | {"upload-buffer-size", {CURLOPT_UPLOAD_BUFFERSIZE, JANET_NUMBER}},
590 | {"upkeep-interval-ms", {CURLOPT_UPKEEP_INTERVAL_MS, JANET_NUMBER}},
591 |
592 | {"in-file-size-large", {CURLOPT_INFILESIZE_LARGE, JANET_NUMBER}},
593 | {"resume-from-large", {CURLOPT_RESUME_FROM_LARGE, JANET_NUMBER}},
594 | {"max-file-size-large", {CURLOPT_MAXFILESIZE_LARGE, JANET_NUMBER}},
595 | {"post-field-size-large", {CURLOPT_POSTFIELDSIZE_LARGE, JANET_NUMBER}},
596 | {"max-send-speed-large", {CURLOPT_MAX_SEND_SPEED_LARGE, JANET_NUMBER}},
597 | {"max-recv-speed-large", {CURLOPT_MAX_RECV_SPEED_LARGE, JANET_NUMBER}},
598 | {"time-value-large", {CURLOPT_TIMEVALUE_LARGE, JANET_NUMBER}},
599 |
600 | {"write-function", {CURLOPT_WRITEFUNCTION, JANET_FUNCTION}},
601 | {"header-function", {CURLOPT_HEADERFUNCTION, JANET_FUNCTION}},
602 | {"read-function", {CURLOPT_READFUNCTION, JANET_FUNCTION}},
603 | {"progress-function", {CURLOPT_PROGRESSFUNCTION, JANET_FUNCTION}},
604 | {"debug-function#TODO", {CURLOPT_DEBUGFUNCTION, JANET_FUNCTION}}, // TODO
605 | {"ssl-ctx-function#TODO", {CURLOPT_SSL_CTX_FUNCTION, JANET_FUNCTION}}, // TODO
606 | {"ioctl-function#TODO", {CURLOPT_IOCTLFUNCTION, JANET_FUNCTION}}, // TODO
607 | {"conv-from-network-function#TODO", {CURLOPT_CONV_FROM_NETWORK_FUNCTION, JANET_FUNCTION}}, // TODO
608 | {"conv-to-network-function#TODO", {CURLOPT_CONV_TO_NETWORK_FUNCTION, JANET_FUNCTION}}, // TODO
609 | {"conv-from-utf8-function#TODO", {CURLOPT_CONV_FROM_UTF8_FUNCTION, JANET_FUNCTION}}, // TODO
610 | {"sockopt-function#TODO", {CURLOPT_SOCKOPTFUNCTION, JANET_FUNCTION}}, // TODO
611 | {"open-socket-function#TODO", {CURLOPT_OPENSOCKETFUNCTION, JANET_FUNCTION}}, // TODO
612 | {"seek-function#TODO", {CURLOPT_SEEKFUNCTION, JANET_FUNCTION}}, // TODO
613 | {"ssh-key-function#TODO", {CURLOPT_SSH_KEYFUNCTION, JANET_FUNCTION}}, // TODO
614 | {"interleave-function#TODO", {CURLOPT_INTERLEAVEFUNCTION, JANET_FUNCTION}}, // TODO
615 | {"chunk-bgn-function#TODO", {CURLOPT_CHUNK_BGN_FUNCTION, JANET_FUNCTION}}, // TODO
616 | {"chunk-end-function#TODO", {CURLOPT_CHUNK_END_FUNCTION, JANET_FUNCTION}}, // TODO
617 | {"fnmatch-function#TODO", {CURLOPT_FNMATCH_FUNCTION, JANET_FUNCTION}}, // TODO
618 | {"close-socket-function#TODO", {CURLOPT_CLOSESOCKETFUNCTION, JANET_FUNCTION}}, // TODO
619 | {"xfer-info-function#TODO", {CURLOPT_XFERINFOFUNCTION, JANET_FUNCTION}}, // TODO
620 | {"resolver-start-function#TODO", {CURLOPT_RESOLVER_START_FUNCTION, JANET_FUNCTION}}, // TODO
621 | {"trailer-function#TODO", {CURLOPT_TRAILERFUNCTION, JANET_FUNCTION}}, // TODO
622 |
623 | {"write-data", {CURLOPT_WRITEDATA, JANET_POINTER}},
624 | {"header-data", {CURLOPT_HEADERDATA, JANET_POINTER}},
625 | {"read-data", {CURLOPT_READDATA, JANET_POINTER}},
626 | {"progress-data", {CURLOPT_PROGRESSDATA, JANET_POINTER}},
627 | {"http-header", {CURLOPT_HTTPHEADER, JANET_POINTER}},
628 | {"error-buffer@TODO", {CURLOPT_ERRORBUFFER, JANET_POINTER}}, // TODO
629 | {"http-post@TODO", {CURLOPT_HTTPPOST, JANET_POINTER}}, // TODO
630 | {"quote@TODO", {CURLOPT_QUOTE, JANET_POINTER}}, // TODO
631 | {"stderr@TODO", {CURLOPT_STDERR, JANET_POINTER}}, // TODO
632 | {"post-quote@TODO", {CURLOPT_POSTQUOTE, JANET_POINTER}}, // TODO
633 | {"obsolete40@TODO", {CURLOPT_OBSOLETE40, JANET_POINTER}}, // TODO
634 | {"telnet-options@TODO", {CURLOPT_TELNETOPTIONS, JANET_POINTER}}, // TODO
635 | {"prequote@TODO", {CURLOPT_PREQUOTE, JANET_POINTER}}, // TODO
636 | {"debug-data@TODO", {CURLOPT_DEBUGDATA, JANET_POINTER}}, // TODO
637 | {"share@TODO", {CURLOPT_SHARE, JANET_POINTER}}, // TODO
638 | {"private@TODO", {CURLOPT_PRIVATE, JANET_POINTER}}, // TODO
639 | {"http200-aliases@TODO", {CURLOPT_HTTP200ALIASES, JANET_POINTER}}, // TODO
640 | {"ssl-ctx-data@TODO", {CURLOPT_SSL_CTX_DATA, JANET_POINTER}}, // TODO
641 | {"ioctl-data@TODO", {CURLOPT_IOCTLDATA, JANET_POINTER}}, // TODO
642 | {"sockopt-data@TODO", {CURLOPT_SOCKOPTDATA, JANET_POINTER}}, // TODO
643 | {"open-socket-data@TODO", {CURLOPT_OPENSOCKETDATA, JANET_POINTER}}, // TODO
644 | {"seek-data@TODO", {CURLOPT_SEEKDATA, JANET_POINTER}}, // TODO
645 | {"ssh-key-data@TODO", {CURLOPT_SSH_KEYDATA, JANET_POINTER}}, // TODO
646 | {"mail-rcpt@TODO", {CURLOPT_MAIL_RCPT, JANET_POINTER}}, // TODO
647 | {"interleave-data@TODO", {CURLOPT_INTERLEAVEDATA, JANET_POINTER}}, // TODO
648 | {"chunk-data@TODO", {CURLOPT_CHUNK_DATA, JANET_POINTER}}, // TODO
649 | {"fnmatch-data@TODO", {CURLOPT_FNMATCH_DATA, JANET_POINTER}}, // TODO
650 | {"resolve@TODO", {CURLOPT_RESOLVE, JANET_POINTER}}, // TODO
651 | {"close-socket-data@TODO", {CURLOPT_CLOSESOCKETDATA, JANET_POINTER}}, // TODO
652 | {"proxy-header@TODO", {CURLOPT_PROXYHEADER, JANET_POINTER}}, // TODO
653 | {"stream-depends@TODO", {CURLOPT_STREAM_DEPENDS, JANET_POINTER}}, // TODO
654 | {"stream-depends-e@TODO", {CURLOPT_STREAM_DEPENDS_E, JANET_POINTER}}, // TODO
655 | {"connect-to@TODO", {CURLOPT_CONNECT_TO, JANET_POINTER}}, // TODO
656 | {"mimepost@TODO", {CURLOPT_MIMEPOST, JANET_POINTER}}, // TODO
657 | {"resolver-start-data@TODO", {CURLOPT_RESOLVER_START_DATA, JANET_POINTER}}, // TODO
658 | {"curlu@TODO", {CURLOPT_CURLU, JANET_POINTER}}, // TODO
659 | {"trailer-data@TODO", {CURLOPT_TRAILERDATA, JANET_POINTER}}, // TODO
660 | };
661 |
662 | static void options_gen_dict(void) {
663 | int32_t size = sizeof(_key_option_type_arr) / sizeof(_key_option_type_arr[0]);
664 |
665 | if (NULL == hashmap_opt_to_type) {
666 | hashmap_opt_to_type = kh_init(HashMapCurlOptionToJanetType);
667 | }
668 |
669 | int absent;
670 | khint_t where;
671 | for (int32_t idx = 0; idx < size; idx++) {
672 | where = kh_put(HashMapCurlOptionToJanetType, hashmap_opt_to_type, _key_option_type_arr[idx].name, &absent);
673 | kh_value(hashmap_opt_to_type, where) = &_key_option_type_arr[idx].kjm;
674 | }
675 | }
676 |
677 | static const MapCurlOptionToJanetType *options_get(const char *key) {
678 | MapCurlOptionToJanetType *val;
679 | khint_t where = kh_get(HashMapCurlOptionToJanetType, hashmap_opt_to_type, key);
680 | val = kh_val(hashmap_opt_to_type, where);
681 | return val;
682 | }
683 |
684 | static struct curl_slist *fill_list_from_tuple(Janet tuple) {
685 | const JanetTupleHead *t = janet_tuple_head(janet_unwrap_tuple(tuple));
686 | if (t->length <= 0) {
687 | janet_panic("input list cannot be empty");
688 | }
689 |
690 | const char *str1 = (const char *) janet_unwrap_string(t->data[0]);
691 | struct curl_slist *list = curl_slist_append(NULL, str1);
692 |
693 | for (int32_t idx = 1; idx < t->length; idx++) {
694 | const char *str = (const char *) janet_unwrap_string(t->data[idx]);
695 | list = curl_slist_append(list, str);
696 | }
697 |
698 | return list;
699 | }
700 |
701 | static struct curl_slist *fill_list_from_array(Janet array) {
702 | const JanetArray *a = janet_unwrap_array(array);
703 | if (a->count <= 0) {
704 | janet_panic("input list cannot be empty");
705 | }
706 |
707 | const char *str1 = (const char *) janet_unwrap_string(a->data[0]);
708 | struct curl_slist *list = curl_slist_append(NULL, str1);
709 |
710 | for (int32_t idx = 1; idx < a->count; idx++) {
711 | const char *str = (const char *) janet_unwrap_string(a->data[idx]);
712 | list = curl_slist_append(list, str);
713 | }
714 |
715 | return list;
716 | }
717 |
718 | static void options_set(Curl *c, Janet *key, Janet *val) {
719 | const char *keyword = (const char *) janet_unwrap_keyword(*key);
720 | const MapCurlOptionToJanetType *map = options_get(keyword);
721 | CURL *curl = c->curl;
722 | if (NULL == map) {
723 | janet_panic("invalid keyword");
724 | }
725 |
726 | int type = map->type;
727 | int opt = map->option;
728 | JanetFunction *fn;
729 |
730 | switch (type) {
731 | case JANET_NUMBER:
732 | if (!janet_checkint(*val)) janet_panicf("expected integer, got %v", *val);
733 | curl_easy_setopt(curl, opt, janet_unwrap_integer(*val));
734 | break;
735 | case JANET_BOOLEAN:
736 | curl_easy_setopt(curl, opt, janet_unwrap_boolean(*val));
737 | break;
738 | case JANET_STRING:
739 | curl_easy_setopt(curl, opt, janet_unwrap_string(*val));
740 | break;
741 | case JANET_FUNCTION:
742 | fn = janet_unwrap_function(*val);
743 | if (0 == strcmp(keyword, "write-function")) {
744 | curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)fn);
745 | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, funcs_write);
746 | c->write_function = fn;
747 | } else if (0 == strcmp(keyword, "header-function")) {
748 | curl_easy_setopt(curl, CURLOPT_HEADERDATA, (void *)fn);
749 | curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, funcs_write);
750 | c->header_function = fn;
751 | } else if (0 == strcmp(keyword, "read-function")) {
752 | curl_easy_setopt(curl, CURLOPT_READDATA, (void *)fn);
753 | curl_easy_setopt(curl, CURLOPT_READFUNCTION, funcs_read);
754 | c->read_function = fn;
755 | } else if (0 == strcmp(keyword, "progress-function")) {
756 | curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, (void *)fn);
757 | curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, funcs_progress);
758 | c->progress_function = fn;
759 | }
760 |
761 | break;
762 | case JANET_POINTER:
763 | if (0 == strcmp(keyword, "http-header")) {
764 | struct curl_slist *list;
765 | if (janet_checktype(*val, JANET_TUPLE) != 0) {
766 | list = fill_list_from_tuple(*val);
767 | } else if (janet_checktype(*val, JANET_ARRAY) != 0) {
768 | list = fill_list_from_array(*val);
769 | } else {
770 | janet_panic("header must be an array or a tuple");
771 | }
772 |
773 | curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
774 | } else {
775 | janet_panic("not implemented yet");
776 | }
777 | // TODO:
778 | break;
779 | default:
780 | janet_panic("value type is not supported");
781 | break;
782 | };
783 | }
784 |
785 | //==============================================================================
786 | // ██╗███╗ ██╗███████╗ ██████╗
787 | // ██║████╗ ██║██╔════╝██╔═══██╗
788 | // ██║██╔██╗ ██║█████╗ ██║ ██║
789 | // ██║██║╚██╗██║██╔══╝ ██║ ██║
790 | // ██║██║ ╚████║██║ ╚██████╔╝
791 | // ╚═╝╚═╝ ╚═══╝╚═╝ ╚═════╝
792 | //==============================================================================
793 |
794 | static struct {
795 | char name[64];
796 | MapCurlInfoToJanetType ijm;
797 | } _key_info_type_arr[] = {
798 | {"query-effective-url", {CURLINFO_EFFECTIVE_URL, JANET_STRING}},
799 | {"query-content-type", {CURLINFO_CONTENT_TYPE, JANET_STRING}},
800 | {"query-private", {CURLINFO_PRIVATE, JANET_STRING}},
801 | {"query-ftp-entry-path", {CURLINFO_FTP_ENTRY_PATH, JANET_STRING}},
802 | {"query-redirect-url", {CURLINFO_REDIRECT_URL, JANET_STRING}},
803 | {"query-primary-ip", {CURLINFO_PRIMARY_IP, JANET_STRING}},
804 | {"query-rtsp-session-id", {CURLINFO_RTSP_SESSION_ID, JANET_STRING}},
805 | {"query-local-ip", {CURLINFO_LOCAL_IP, JANET_STRING}},
806 | {"query-scheme", {CURLINFO_SCHEME, JANET_STRING}},
807 |
808 | {"query-response-code", {CURLINFO_RESPONSE_CODE, JANET_NUMBER}},
809 | {"query-total-time", {CURLINFO_TOTAL_TIME, JANET_NUMBER}},
810 | {"query-name-lookup-time", {CURLINFO_NAMELOOKUP_TIME, JANET_NUMBER}},
811 | {"query-connect-time", {CURLINFO_CONNECT_TIME, JANET_NUMBER}},
812 | {"query-pre-transfer-time", {CURLINFO_PRETRANSFER_TIME, JANET_NUMBER}},
813 | {"query-size-upload", {CURLINFO_SIZE_UPLOAD, JANET_NUMBER}},
814 | {"query-size-upload-t", {CURLINFO_SIZE_UPLOAD_T, JANET_NUMBER}},
815 | {"query-size-download", {CURLINFO_SIZE_DOWNLOAD, JANET_NUMBER}},
816 | {"query-size-download-t", {CURLINFO_SIZE_DOWNLOAD_T, JANET_NUMBER}},
817 | {"query-speed-download", {CURLINFO_SPEED_DOWNLOAD, JANET_NUMBER}},
818 | {"query-speed-download-t", {CURLINFO_SPEED_DOWNLOAD_T, JANET_NUMBER}},
819 | {"query-speed-upload", {CURLINFO_SPEED_UPLOAD, JANET_NUMBER}},
820 | {"query-speed-upload-t", {CURLINFO_SPEED_UPLOAD_T, JANET_NUMBER}},
821 | {"query-header-size", {CURLINFO_HEADER_SIZE, JANET_NUMBER}},
822 | {"query-request-size", {CURLINFO_REQUEST_SIZE, JANET_NUMBER}},
823 | {"query-ssl-verify-result", {CURLINFO_SSL_VERIFYRESULT, JANET_NUMBER}},
824 | {"query-file-time", {CURLINFO_FILETIME, JANET_NUMBER}},
825 | {"query-file-time-t", {CURLINFO_FILETIME_T, JANET_NUMBER}},
826 | {"query-content-length-download", {CURLINFO_CONTENT_LENGTH_DOWNLOAD, JANET_NUMBER}},
827 | {"query-content-length-download-t", {CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, JANET_NUMBER}},
828 | {"query-content-length-upload", {CURLINFO_CONTENT_LENGTH_UPLOAD, JANET_NUMBER}},
829 | {"query-content-length-upload-t", {CURLINFO_CONTENT_LENGTH_UPLOAD_T, JANET_NUMBER}},
830 | {"query-start-transfer-time", {CURLINFO_STARTTRANSFER_TIME, JANET_NUMBER}},
831 | {"query-redirect-time", {CURLINFO_REDIRECT_TIME, JANET_NUMBER}},
832 | {"query-redirect-count", {CURLINFO_REDIRECT_COUNT, JANET_NUMBER}},
833 | {"query-http-connect-code", {CURLINFO_HTTP_CONNECTCODE, JANET_NUMBER}},
834 | {"query-http-auth-avail", {CURLINFO_HTTPAUTH_AVAIL, JANET_NUMBER}},
835 | {"query-proxy-auth-avail", {CURLINFO_PROXYAUTH_AVAIL, JANET_NUMBER}},
836 | {"query-os-errno", {CURLINFO_OS_ERRNO, JANET_NUMBER}},
837 | {"query-num-connects", {CURLINFO_NUM_CONNECTS, JANET_NUMBER}},
838 | {"query-last-socket", {CURLINFO_LASTSOCKET, JANET_NUMBER}},
839 | {"query-app-connect-time", {CURLINFO_APPCONNECT_TIME, JANET_NUMBER}},
840 | {"query-condition-unmet", {CURLINFO_CONDITION_UNMET, JANET_NUMBER}},
841 | {"query-rtsp-client-cseq", {CURLINFO_RTSP_CLIENT_CSEQ, JANET_NUMBER}},
842 | {"query-rtsp-server-cseq", {CURLINFO_RTSP_SERVER_CSEQ, JANET_NUMBER}},
843 | {"query-rtsp-cseq-recv", {CURLINFO_RTSP_CSEQ_RECV, JANET_NUMBER}},
844 | {"query-primary-port", {CURLINFO_PRIMARY_PORT, JANET_NUMBER}},
845 | {"query-local-port", {CURLINFO_LOCAL_PORT, JANET_NUMBER}},
846 | {"query-http-version", {CURLINFO_HTTP_VERSION, JANET_NUMBER}},
847 | {"query-proxy-ssl-verify-result", {CURLINFO_PROXY_SSL_VERIFYRESULT, JANET_NUMBER}},
848 | {"query-protocol", {CURLINFO_PROTOCOL, JANET_NUMBER}},
849 | {"query-total-time-t", {CURLINFO_TOTAL_TIME_T, JANET_NUMBER}},
850 | {"query-name-lookup-time-t", {CURLINFO_NAMELOOKUP_TIME_T, JANET_NUMBER}},
851 | {"query-connect-time-t", {CURLINFO_CONNECT_TIME_T, JANET_NUMBER}},
852 | {"query-pre-transfer-time-t", {CURLINFO_PRETRANSFER_TIME_T, JANET_NUMBER}},
853 | {"query-start-transfer-time-t", {CURLINFO_STARTTRANSFER_TIME_T, JANET_NUMBER}},
854 | {"query-redirect-time-t", {CURLINFO_REDIRECT_TIME_T, JANET_NUMBER}},
855 | {"query-app-connect-time-t", {CURLINFO_APPCONNECT_TIME_T, JANET_NUMBER}},
856 |
857 | {"query-ssl-engines", {CURLINFO_SSL_ENGINES, JANET_POINTER}}, // TODO:
858 | {"query-cookie-list", {CURLINFO_COOKIELIST, JANET_POINTER}}, // TODO:
859 | {"query-cert-info", {CURLINFO_CERTINFO, JANET_POINTER}}, // TODO:
860 | {"query-tls-session", {CURLINFO_TLS_SESSION, JANET_POINTER}}, // TODO:
861 | {"query-active-socket", {CURLINFO_ACTIVESOCKET, JANET_POINTER}}, // TODOL
862 | {"query-tls-ssl-ptr", {CURLINFO_TLS_SSL_PTR, JANET_POINTER}}, // TODO:
863 | };
864 |
865 | static void info_gen_dict(void) {
866 | int32_t size = sizeof(_key_info_type_arr) / sizeof(_key_info_type_arr[0]);
867 |
868 | if (NULL == hashmap_info_to_type) {
869 | hashmap_info_to_type = kh_init(HashMapCurlInfoToJanetType);
870 | }
871 |
872 | int absent;
873 | khint_t where;
874 | for (int32_t idx = 0; idx < size; idx++) {
875 | where = kh_put(HashMapCurlInfoToJanetType, hashmap_info_to_type, _key_info_type_arr[idx].name, &absent);
876 | kh_value(hashmap_info_to_type, where) = &_key_info_type_arr[idx].ijm;
877 | }
878 | }
879 |
880 | static const MapCurlInfoToJanetType *info_get(const char *key) {
881 | MapCurlInfoToJanetType *val;
882 | khint_t where = kh_get(HashMapCurlInfoToJanetType, hashmap_info_to_type, key);
883 | val = kh_val(hashmap_info_to_type, where);
884 | return val;
885 | }
886 |
887 | static Janet info_query(CURL *curl, Janet *key) {
888 | const char *keyword = (const char *) janet_unwrap_keyword(*key);
889 | const MapCurlInfoToJanetType *map = info_get(keyword);
890 | if (NULL == map) {
891 | janet_panic("invalid keyword");
892 | }
893 |
894 | int type = map->type;
895 | int info = map->info;
896 |
897 | int32_t res_number;
898 | const char *res_string;
899 |
900 | switch (type) {
901 | case JANET_NUMBER:
902 | if (CURLE_OK == curl_easy_getinfo(curl, info, &res_number)) {
903 | return janet_wrap_integer(res_number);
904 | }
905 | break;
906 | case JANET_STRING:
907 | if (CURLE_OK == curl_easy_getinfo(curl, info, &res_string)) {
908 | return janet_wrap_string((const char *)res_string);
909 | }
910 | break;
911 | default:
912 | janet_panic("value type is not supported");
913 | break;
914 | };
915 |
916 | return janet_wrap_false();
917 | }
918 |
919 | //==============================================================================
920 | // ███████╗ █████╗ ███████╗██╗ ██╗
921 | // ██╔════╝██╔══██╗██╔════╝╚██╗ ██╔╝
922 | // █████╗ ███████║███████╗ ╚████╔╝
923 | // ██╔══╝ ██╔══██║╚════██║ ╚██╔╝
924 | // ███████╗██║ ██║███████║ ██║
925 | // ╚══════╝╚═╝ ╚═╝╚══════╝ ╚═╝
926 | //==============================================================================
927 |
928 | static Janet easy_init(int32_t argc, Janet *argv) {
929 | janet_fixarity(argc, 0);
930 | (void)argv;
931 |
932 | CURL *curl = curl_easy_init();
933 | return curl ? curl_make(curl) : janet_wrap_nil();
934 | }
935 |
936 | static Janet easy_clone(int32_t argc, Janet *argv) {
937 | janet_fixarity(argc, 1);
938 |
939 | Curl *curl = janet_getabstract(argv, 0, &curl_obj);
940 | CURL *clone = curl_easy_duphandle(curl->curl);
941 |
942 | return clone ? curl_make(clone) : janet_wrap_nil();
943 | }
944 |
945 | static Janet easy_escape(int32_t argc, Janet *argv) {
946 | janet_fixarity(argc, 2);
947 |
948 | Curl *curl = janet_getabstract(argv, 0, &curl_obj);
949 | const char *iurl = janet_getcstring(argv, 1);
950 | if (NULL == iurl) {
951 | janet_panic("input url string is invalid or null");
952 | }
953 |
954 | int len = strlen(iurl);
955 | if (0 >= len) {
956 | janet_panic("input url cannot be empty");
957 | }
958 |
959 | char *ourl = curl_easy_escape(curl->curl, iurl, len);
960 | if (NULL == ourl) {
961 | curl_free(ourl);
962 | return janet_wrap_false();
963 | }
964 |
965 | Janet res = janet_cstringv(ourl);
966 | curl_free(ourl);
967 |
968 | return res;
969 | }
970 |
971 | static Janet easy_unescape(int32_t argc, Janet *argv) {
972 | janet_fixarity(argc, 2);
973 |
974 | Curl *curl = janet_getabstract(argv, 0, &curl_obj);
975 | const char *iurl = janet_getcstring(argv, 1);
976 | if (NULL == iurl) {
977 | janet_panic("input url string is invalid or null");
978 | }
979 |
980 | int ilen = strlen(iurl);
981 | if (0 >= ilen) {
982 | janet_panic("input url cannot be empty");
983 | }
984 |
985 | int olen = 0;
986 |
987 | char *ourl = curl_easy_unescape(curl->curl, iurl, ilen, &olen);
988 | if (NULL == ourl || 0 >= olen) {
989 | return janet_wrap_false();
990 | }
991 |
992 | Janet res = janet_cstringv(ourl);
993 | curl_free(ourl);
994 |
995 | return res;
996 | }
997 |
998 | static Janet easy_strerror(int32_t argc, Janet *argv) {
999 | janet_fixarity(argc, 1);
1000 |
1001 | int code = janet_getinteger(argv, 0);
1002 |
1003 | const char *errstr = curl_easy_strerror(code);
1004 | Janet res = janet_cstringv(errstr);
1005 |
1006 | return res;
1007 | }
1008 |
1009 | static Janet easy_setopt(int32_t argc, Janet *argv) {
1010 | janet_arity(argc, 2, -1);
1011 |
1012 | if ((argc - 1) % 2 != 0) {
1013 | janet_panic("options count must be even, options are regarded as tuple");
1014 | }
1015 |
1016 | Curl *curl = janet_getabstract(argv, 0, &curl_obj);
1017 |
1018 | for (int32_t idx = 1; idx < argc; idx += 2) {
1019 | options_set(curl, argv + idx, argv + idx + 1);
1020 | }
1021 |
1022 | return janet_wrap_true();
1023 | }
1024 |
1025 | static Janet easy_pause(int32_t argc, Janet *argv) {
1026 | janet_fixarity(argc, 2);
1027 |
1028 | Curl *curl = janet_getabstract(argv, 0, &curl_obj);
1029 | const char *modestr = (const char *) janet_getkeyword(argv, 1);
1030 |
1031 | int mode = -1;
1032 | if (0 == strcmp(modestr, "pause-mode-recv")) {
1033 | mode = CURLPAUSE_RECV;
1034 | } else if (0 == strcmp(modestr, "pause-mode-send")) {
1035 | mode = CURLPAUSE_SEND;
1036 | } else if (0 == strcmp(modestr, "paus-modee-all")) {
1037 | mode = CURLPAUSE_ALL;
1038 | } else if (0 == strcmp(modestr, "pause-mode-cont")) {
1039 | mode = CURLPAUSE_CONT;
1040 | } else {
1041 | janet_panic("invalid pause mode");
1042 | }
1043 |
1044 | curl_easy_pause(curl->curl, mode);
1045 | return janet_wrap_true();
1046 | }
1047 |
1048 | static Janet easy_reset(int32_t argc, Janet *argv) {
1049 | janet_fixarity(argc, 1);
1050 |
1051 | Curl *curl = janet_getabstract(argv, 0, &curl_obj);
1052 |
1053 | curl_easy_reset(curl->curl);
1054 | return janet_wrap_nil();
1055 | }
1056 |
1057 | static Janet easy_upkeep(int32_t argc, Janet *argv) {
1058 | janet_fixarity(argc, 1);
1059 |
1060 | Curl *curl = janet_getabstract(argv, 0, &curl_obj);
1061 |
1062 | curl_easy_upkeep(curl->curl);
1063 | return janet_wrap_nil();
1064 | }
1065 |
1066 | static Janet easy_recv(int32_t argc, Janet *argv) {
1067 | janet_arity(argc, 1, 2);
1068 |
1069 | Curl *curl = janet_getabstract(argv, 0, &curl_obj);
1070 |
1071 | size_t buflen = DEFAULT_EASY_RECV_BUF_LEN;
1072 | size_t recvlen = -1;
1073 | if (argc == 2) {
1074 | buflen = janet_getinteger(argv, 1);
1075 | }
1076 |
1077 | char *buffer = (char *) calloc(buflen, sizeof(char));
1078 | int res = curl_easy_recv(curl->curl, buffer, buflen, &recvlen);
1079 | JanetBuffer *jbuff = janet_buffer(buflen);
1080 | janet_buffer_push_bytes(jbuff, (const uint8_t *)buffer, buflen);
1081 | free(buffer);
1082 |
1083 | // TODO: i am not satisfied with this function
1084 |
1085 | if (0 == recvlen) {
1086 | return janet_ckeywordv("closed");
1087 | }
1088 |
1089 | switch (res) {
1090 | case CURLE_OK:
1091 | return janet_wrap_buffer(jbuff);
1092 | break;
1093 | case CURLE_AGAIN:
1094 | return janet_ckeywordv("more");
1095 | break;
1096 | case CURLE_UNSUPPORTED_PROTOCOL:
1097 | return janet_ckeywordv("unsopported");
1098 | break;
1099 | default:
1100 | return janet_wrap_false();
1101 | }
1102 | }
1103 |
1104 | static Janet easy_send(int32_t argc, Janet *argv) {
1105 | janet_fixarity(argc, 2);
1106 |
1107 | Curl *curl = janet_getabstract(argv, 0, &curl_obj);
1108 |
1109 | size_t sendlen = -1;
1110 | JanetByteView buffer = janet_getbytes(argv, 1);
1111 |
1112 | int res = curl_easy_send(curl->curl, buffer.bytes, buffer.len, &sendlen);
1113 |
1114 | switch (res) {
1115 | case CURLE_OK:
1116 | return janet_wrap_true();
1117 | break;
1118 | case CURLE_AGAIN:
1119 | return janet_ckeywordv("more");
1120 | break;
1121 | case CURLE_UNSUPPORTED_PROTOCOL:
1122 | return janet_ckeywordv("unsopported");
1123 | break;
1124 | default:
1125 | return janet_wrap_false();
1126 | }
1127 | }
1128 |
1129 | static Janet easy_perform(int32_t argc, Janet *argv) {
1130 | janet_fixarity(argc, 1);
1131 |
1132 | Curl *curl = janet_getabstract(argv, 0, &curl_obj);
1133 |
1134 | CURLcode res;
1135 | res = curl_easy_perform(curl->curl);
1136 | return janet_wrap_integer(res);
1137 | }
1138 |
1139 | static Janet easy_query(int32_t argc, Janet *argv) {
1140 | janet_fixarity(argc, 2);
1141 |
1142 | Curl *curl = janet_getabstract(argv, 0, &curl_obj);
1143 |
1144 | return info_query(curl->curl, argv + 1);
1145 | }
1146 |
1147 | static const JanetReg curl_easy_cfuns[] = {
1148 | {
1149 | "easy/init", easy_init,
1150 | "(def curl (easy/init)) \n\n"
1151 | "create a new curl handler"
1152 | },
1153 | {
1154 | "easy/clone", easy_clone,
1155 | "(easy/clone curl) \n\n"
1156 | "clones a libcurl session handle"
1157 | },
1158 | {
1159 | "easy/escape", easy_escape,
1160 | "(easy/escape curl \"https://janet-lang.org\") \n\n"
1161 | "encode the input string as an url escaped string"
1162 | },
1163 | {
1164 | "easy/unescape", easy_unescape,
1165 | "(easy/unescape curl \"https\%3A\%2F\%2Fjanet-lang.org\") \n\n"
1166 | "decode the input url string as an unescape string"
1167 | },
1168 | {
1169 | "easy/strerror", easy_strerror,
1170 | "(easy/strerror code) \n\n"
1171 | "return error string of an error code"
1172 | },
1173 | {
1174 | "easy/setopt", easy_setopt,
1175 | "(easy/setopt code :url \"https://janet-lang.org\") \n\n"
1176 | "set options for a curl easy handle"
1177 | },
1178 | {
1179 | "easy/pause", easy_pause,
1180 | "(easy/pause curl :pause_mode_all) \n\n"
1181 | "pause and unpause a connection"
1182 | },
1183 | {
1184 | "easy/reset", easy_reset,
1185 | "(easy/reset curl) \n\n"
1186 | "reset all options of a libcurl session handle"
1187 | },
1188 | {
1189 | "easy/upkeep", easy_upkeep,
1190 | "(easy/upkeep curl) \n\n"
1191 | "perform any connection upkeep checks"
1192 | },
1193 | {
1194 | "easy/recv", easy_recv,
1195 | "(easy/recv curl) \n\n"
1196 | "receives raw data on an \"easy\" connection"
1197 | },
1198 | {
1199 | "easy/send", easy_send,
1200 | "(easy/send curl) \n\n"
1201 | "sends raw data over an \"easy\" connection"
1202 | },
1203 | {
1204 | "easy/perform", easy_perform,
1205 | "(easy/perform curl) \n\n"
1206 | "perform a blocking file transfer"
1207 | },
1208 | {
1209 | "easy/query", easy_query,
1210 | "(easy/query curl :query-effective-url) \n\n"
1211 | "query information from curl easy handler"
1212 | },
1213 | {NULL, NULL, NULL}
1214 | };
1215 |
1216 | static void submod_easy(JanetTable *env) {
1217 | janet_cfuns(env, "curl", curl_easy_cfuns);
1218 | }
1219 |
1220 | //==============================================================================
1221 | // ███████╗██╗ ██╗ █████╗ ██████╗ ███████╗
1222 | // ██╔════╝██║ ██║██╔══██╗██╔══██╗██╔════╝
1223 | // ███████╗███████║███████║██████╔╝█████╗
1224 | // ╚════██║██╔══██║██╔══██║██╔══██╗██╔══╝
1225 | // ███████║██║ ██║██║ ██║██║ ██║███████╗
1226 | // ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝
1227 | //==============================================================================
1228 |
1229 | static Janet share_init(int32_t argc, Janet *argv) {
1230 | janet_fixarity(argc, 0);
1231 | (void)argv;
1232 |
1233 | CURLSH *curlsh = curl_share_init();
1234 | return curlsh ? curlsh_make(curlsh) : janet_wrap_nil();
1235 | }
1236 |
1237 | static Janet share_setopt(int32_t argc, Janet *argv) {
1238 | janet_arity(argc, 2, -1);
1239 |
1240 | if ((argc - 1) % 2 != 0) {
1241 | janet_panic("options count must be even, options are regarded as tuple");
1242 | }
1243 |
1244 | janet_panic("this function is implemented yet");
1245 |
1246 | (void) argv;
1247 | // Curl* curl = janet_getabstract(argv, 0, &curl_obj);
1248 |
1249 | // for (int32_t idx = 1; idx < argc; idx+=2){
1250 | // options_set(curl, argv + idx, argv + idx + 1);
1251 | // }
1252 |
1253 | return janet_wrap_true();
1254 | }
1255 |
1256 | static Janet share_strerror(int32_t argc, Janet *argv) {
1257 | janet_fixarity(argc, 1);
1258 |
1259 | int code = janet_getinteger(argv, 0);
1260 |
1261 | const char *errstr = curl_share_strerror(code);
1262 | Janet res = janet_cstringv(errstr);
1263 |
1264 | return res;
1265 | }
1266 |
1267 | static const JanetReg curl_share_cfuns[] = {
1268 | {
1269 | "share/init", share_init,
1270 | "(def curl (share/init)) \n\n"
1271 | "create a new curl share handler"
1272 | },
1273 | {
1274 | "share/strerror", share_strerror,
1275 | "(share/strerror code) \n\n"
1276 | "return error string of an error code"
1277 | },
1278 | {
1279 | "share/setopt", share_setopt,
1280 | "(share/setopt code :url \"https://janet-lang.org\") \n\n"
1281 | "set options for a curl share handle"
1282 | },
1283 | {NULL, NULL, NULL}
1284 | };
1285 |
1286 | static void submod_share(JanetTable *env) {
1287 | janet_cfuns(env, "curl", curl_share_cfuns);
1288 | }
1289 |
1290 | //==============================================================================
1291 | // ██╗ ██╗██████╗ ██╗
1292 | // ██║ ██║██╔══██╗██║
1293 | // ██║ ██║██████╔╝██║
1294 | // ██║ ██║██╔══██╗██║
1295 | // ╚██████╔╝██║ ██║███████╗
1296 | // ╚═════╝ ╚═╝ ╚═╝╚══════╝
1297 | //==============================================================================
1298 |
1299 | static Janet url_init(int32_t argc, Janet *argv) {
1300 | janet_fixarity(argc, 0);
1301 | (void)argv;
1302 |
1303 | CURLU *url = curl_url();
1304 | return url ? url_make(url) : janet_wrap_nil();
1305 | }
1306 |
1307 | static Janet url_clone(int32_t argc, Janet *argv) {
1308 | janet_fixarity(argc, 1);
1309 |
1310 | Url *url = janet_getabstract(argv, 0, &url_obj);
1311 | CURLU *clone = curl_url_dup(url->url);
1312 |
1313 | return clone ? url_make(clone) : janet_wrap_nil();
1314 | }
1315 |
1316 | static Janet url_get(int32_t argc, Janet *argv) {
1317 | janet_arity(argc, 2, 3);
1318 |
1319 | Url *url = janet_getabstract(argv, 0, &url_obj);
1320 | const uint32_t part = janet_getinteger(argv, 1);
1321 | char *extracted;
1322 | uint32_t flag = 0;
1323 |
1324 | if (3 == argc) {
1325 | flag = (uint32_t) janet_getinteger(argv, 2);
1326 | }
1327 |
1328 | if (CURLUE_OK == curl_url_get(url->url, part, &extracted, flag)) {
1329 | Janet res = janet_cstringv(extracted);
1330 | curl_free(extracted);
1331 | return res;
1332 | }
1333 |
1334 | return janet_wrap_nil();
1335 | }
1336 |
1337 | static Janet url_set(int32_t argc, Janet *argv) {
1338 | janet_arity(argc, 3, 4);
1339 |
1340 | Url *url = janet_getabstract(argv, 0, &url_obj);
1341 | const uint32_t part = janet_getinteger(argv, 1);
1342 | const char *extracted = janet_getcstring(argv, 2);
1343 | uint32_t flag = 0;
1344 |
1345 | if (4 == argc) {
1346 | flag = (uint32_t) janet_getinteger(argv, 3);
1347 | }
1348 |
1349 | if (CURLUE_OK == curl_url_set(url->url, part, extracted, flag)) {
1350 | return janet_wrap_true();
1351 | }
1352 |
1353 | return janet_wrap_false();
1354 | }
1355 |
1356 | static const JanetReg curl_url_cfuns[] = {
1357 | {
1358 | "url/init", url_init,
1359 | "(def url (url/init)) \n\n"
1360 | "create a new url object"
1361 | },
1362 | {
1363 | "url/clone", url_clone,
1364 | "(url/clone url) \n\n"
1365 | "clones a url object"
1366 | },
1367 | {
1368 | "url/get", url_get,
1369 | "(url/get url :url-part-host) \n\n"
1370 | "extract a part from a url object"
1371 | },
1372 | {
1373 | "url/set", url_set,
1374 | "(url/set url :url-part-port \"2019\") \n\n"
1375 | "extract a part from a url object"
1376 | },
1377 | {NULL, NULL, NULL}
1378 | };
1379 |
1380 | static void submod_url(JanetTable *env) {
1381 | janet_cfuns(env, "curl", curl_url_cfuns);
1382 | }
1383 |
1384 | //==============================================================================
1385 | // ███╗ ███╗██╗███╗ ███╗███████╗
1386 | // ████╗ ████║██║████╗ ████║██╔════╝
1387 | // ██╔████╔██║██║██╔████╔██║█████╗
1388 | // ██║╚██╔╝██║██║██║╚██╔╝██║██╔══╝
1389 | // ██║ ╚═╝ ██║██║██║ ╚═╝ ██║███████╗
1390 | // ╚═╝ ╚═╝╚═╝╚═╝ ╚═╝╚══════╝
1391 | //==============================================================================
1392 |
1393 | static Janet mime_init(int32_t argc, Janet *argv) {
1394 | janet_fixarity(argc, 1);
1395 |
1396 | Curl *curl = janet_getabstract(argv, 0, &curl_obj);
1397 | curl_mime *mime = curl_mime_init(curl->curl);
1398 |
1399 | return mime ? mime_make(mime) : janet_wrap_nil();
1400 | }
1401 |
1402 | static Janet mime_part(int32_t argc, Janet *argv) {
1403 | janet_fixarity(argc, 1);
1404 |
1405 | Mime *mime = janet_getabstract(argv, 0, &curl_obj);
1406 | curl_mimepart *mimepart = curl_mime_addpart(mime->mime);
1407 |
1408 | return mimepart ? mimepart_make(mimepart) : janet_wrap_nil();
1409 | }
1410 |
1411 | static Janet mime_subpart(int32_t argc, Janet *argv) {
1412 | janet_fixarity(argc, 2);
1413 |
1414 | Mime *mime = janet_getabstract(argv, 0, &curl_obj);
1415 | MimePart *mimepart = janet_getabstract(argv, 1, &curl_obj);
1416 |
1417 | if (CURLE_OK == curl_mime_subparts(mimepart->mimepart, mime->mime)) {
1418 | return janet_wrap_true();
1419 | }
1420 |
1421 | return janet_wrap_false();
1422 | }
1423 |
1424 | static Janet mime_name(int32_t argc, Janet *argv) {
1425 | janet_fixarity(argc, 2);
1426 |
1427 | MimePart *mimepart = janet_getabstract(argv, 0, &curl_obj);
1428 | const char *name = janet_getcstring(argv, 1);
1429 |
1430 | if (CURLE_OK == curl_mime_name(mimepart->mimepart, name)) {
1431 | return janet_wrap_true();
1432 | }
1433 |
1434 | return janet_wrap_false();
1435 | }
1436 |
1437 | static Janet mime_type(int32_t argc, Janet *argv) {
1438 | janet_fixarity(argc, 2);
1439 |
1440 | MimePart *mimepart = janet_getabstract(argv, 0, &curl_obj);
1441 | const char *type = janet_getcstring(argv, 1);
1442 |
1443 | if (CURLE_OK == curl_mime_type(mimepart->mimepart, type)) {
1444 | return janet_wrap_true();
1445 | }
1446 |
1447 | return janet_wrap_false();
1448 | }
1449 |
1450 | static Janet mime_data(int32_t argc, Janet *argv) {
1451 | janet_fixarity(argc, 2);
1452 |
1453 | MimePart *mimepart = janet_getabstract(argv, 0, &curl_obj);
1454 | const JanetBuffer *buffer = janet_getbuffer(argv, 1);
1455 |
1456 | if (CURLE_OK == curl_mime_data(mimepart->mimepart, (const char *)buffer->data, buffer->count)) {
1457 | return janet_wrap_true();
1458 | }
1459 |
1460 | return janet_wrap_false();
1461 | }
1462 |
1463 | static Janet mime_encoder(int32_t argc, Janet *argv) {
1464 | janet_fixarity(argc, 2);
1465 |
1466 | MimePart *mimepart = janet_getabstract(argv, 0, &curl_obj);
1467 | const char *encoding = janet_getcstring(argv, 1);
1468 |
1469 | if (CURLE_OK == curl_mime_encoder(mimepart->mimepart, encoding)) {
1470 | return janet_wrap_true();
1471 | }
1472 |
1473 | return janet_wrap_false();
1474 | }
1475 |
1476 | static Janet mime_headers(int32_t argc, Janet *argv) {
1477 | janet_fixarity(argc, 2);
1478 |
1479 | MimePart *mimepart = janet_getabstract(argv, 0, &curl_obj);
1480 | JanetView array = janet_getindexed(argv, 1);
1481 |
1482 | if (array.len <= 0) {
1483 | janet_panic("input list cannot be empty");
1484 | }
1485 |
1486 | const char *str1 = (const char *) janet_unwrap_string(array.items[0]);
1487 | struct curl_slist *list = curl_slist_append(NULL, str1);
1488 |
1489 | for (int32_t idx = 1; idx < array.len; idx++) {
1490 | const char *str = (const char *) janet_unwrap_string(array.items[idx]);
1491 | list = curl_slist_append(list, str);
1492 | }
1493 |
1494 | const int auto_free = 1;
1495 | if (CURLE_OK == curl_mime_headers(mimepart->mimepart, list, auto_free)) {
1496 | return janet_wrap_true();
1497 | }
1498 |
1499 | return janet_wrap_false();
1500 | }
1501 |
1502 | static Janet mime_filename(int32_t argc, Janet *argv) {
1503 | janet_fixarity(argc, 2);
1504 |
1505 | MimePart *mimepart = janet_getabstract(argv, 0, &curl_obj);
1506 | const char *filename = janet_getcstring(argv, 1);
1507 |
1508 | if (CURLE_OK == curl_mime_filename(mimepart->mimepart, filename)) {
1509 | return janet_wrap_true();
1510 | }
1511 |
1512 | return janet_wrap_false();
1513 | }
1514 |
1515 | static Janet mime_filedata(int32_t argc, Janet *argv) {
1516 | janet_fixarity(argc, 2);
1517 |
1518 | MimePart *mimepart = janet_getabstract(argv, 0, &curl_obj);
1519 | const char *filename = janet_getcstring(argv, 1);
1520 |
1521 | if (CURLE_OK == curl_mime_filedata(mimepart->mimepart, filename)) {
1522 | return janet_wrap_true();
1523 | }
1524 |
1525 | return janet_wrap_false();
1526 | }
1527 |
1528 | static const JanetReg curl_mime_cfuns[] = {
1529 | {
1530 | "mime/init", mime_init,
1531 | "(mime/init curl) \n\n"
1532 | "create a mime handle"
1533 | },
1534 | {
1535 | "mime/part", mime_part,
1536 | "(mime/part mime) \n\n"
1537 | "append a new empty part to a mime object"
1538 | },
1539 | {
1540 | "mime/subpart", mime_subpart,
1541 | "(mime/subpart mimepart mime) \n\n"
1542 | "set subparts of a multipart mime part"
1543 | },
1544 | {
1545 | "mime/name", mime_name,
1546 | "(mime/name mimepart \"wtf\") \n\n"
1547 | "set a mime part's name"
1548 | },
1549 | {
1550 | "mime/type", mime_type,
1551 | "(mime/type mimepart \"image\\png\") \n\n"
1552 | "set a mime part's content type"
1553 | },
1554 | {
1555 | "mime/data", mime_data,
1556 | "(mime/data mimepart buffer) \n\n"
1557 | "set a mime part's content"
1558 | },
1559 | {
1560 | "mime/encoder", mime_encoder,
1561 | "(mime/encoder mimepart buffer) \n\n"
1562 | "set mime data transfer encoder"
1563 | },
1564 | {
1565 | "mime/headers", mime_headers,
1566 | "(mime/headers mimepart [\"aaa\" \"bbb\"]) \n\n"
1567 | "set a mime part's custom headers"
1568 | },
1569 | {
1570 | "mime/filename", mime_filename,
1571 | "(mime/filename mimepart \"myfile.png\") \n\n"
1572 | "set a mime part's remote file name"
1573 | },
1574 | {
1575 | "mime/filedata", mime_filedata,
1576 | "(mime/filedata mimepart \"/home/lol/myfile.png\") \n\n"
1577 | "set a mime part's body data from a file contents"
1578 | },
1579 | {NULL, NULL, NULL}
1580 | };
1581 |
1582 | static void submod_mime(JanetTable *env) {
1583 | janet_cfuns(env, "curl", curl_mime_cfuns);
1584 | }
1585 |
1586 | //==============================================================================
1587 | // ███╗ ███╗ ██████╗ ██████╗ ██╗ ██╗██╗ ███████╗
1588 | // ████╗ ████║██╔═══██╗██╔══██╗██║ ██║██║ ██╔════╝
1589 | // ██╔████╔██║██║ ██║██║ ██║██║ ██║██║ █████╗
1590 | // ██║╚██╔╝██║██║ ██║██║ ██║██║ ██║██║ ██╔══╝
1591 | // ██║ ╚═╝ ██║╚██████╔╝██████╔╝╚██████╔╝███████╗███████╗
1592 | // ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚══════╝
1593 | //==============================================================================
1594 |
1595 | JANET_MODULE_ENTRY(JanetTable *env) {
1596 | options_gen_dict();
1597 | info_gen_dict();
1598 |
1599 | // GENERAL
1600 | janet_def(env, "version", janet_cstringv(LIBCURL_VERSION), "underlying libcurl value string");
1601 |
1602 | // .:ENUMS:.
1603 | // CURLOPT_PROXYTYPE
1604 | janet_def(env, "proxy-type-http", janet_wrap_integer(CURLPROXY_HTTP), "http proxy type");
1605 | janet_def(env, "proxy-type-https", janet_wrap_integer(CURLPROXY_HTTPS), "https proxy type");
1606 | janet_def(env, "proxy-type-http-1.0", janet_wrap_integer(CURLPROXY_HTTP_1_0), "http 1.0 proxy type");
1607 | janet_def(env, "proxy-type-socks4", janet_wrap_integer(CURLPROXY_SOCKS4), "socks4 proxy type");
1608 | janet_def(env, "proxy-type-socks4a", janet_wrap_integer(CURLPROXY_SOCKS4A), "socks4a proxy type");
1609 | janet_def(env, "proxy-type-socks5", janet_wrap_integer(CURLPROXY_SOCKS5), "socks5 proxy type");
1610 | janet_def(env, "proxy-type-socks5-hostname", janet_wrap_integer(CURLPROXY_SOCKS5_HOSTNAME), "socks5 resolver proxy type");
1611 |
1612 | // CURLOPT_FTP_CREATE_MISSING_DIRS
1613 | janet_def(env, "ftp-create-missing-dir-no", janet_wrap_integer(CURLFTP_CREATE_DIR_NONE), "do not create missing dirs");
1614 | janet_def(env, "ftp-create-missing-dir-yes", janet_wrap_integer(CURLFTP_CREATE_DIR), "create missing dirs");
1615 | janet_def(env, "ftp-create-missing-dir-retry", janet_wrap_integer(CURLFTP_CREATE_DIR_RETRY), "retry create missing dirs");
1616 |
1617 | // CURLOPT_IPRESOLVE
1618 | janet_def(env, "ip-resolve-whatever", janet_wrap_integer(CURL_IPRESOLVE_WHATEVER), "whatever");
1619 | janet_def(env, "ip-resolve-v4", janet_wrap_integer(CURL_IPRESOLVE_V4), "v4");
1620 | janet_def(env, "ip-resolve-v6", janet_wrap_integer(CURL_IPRESOLVE_V6), "v6");
1621 |
1622 | // CURLOPT_USE_SSL
1623 | janet_def(env, "use-ssl-none", janet_wrap_integer(CURLUSESSL_NONE), "do not attempt to use ssl");
1624 | janet_def(env, "use-ssl-try", janet_wrap_integer(CURLUSESSL_TRY), "try using ssl, proceed anyway otherwise");
1625 | janet_def(env, "use-ssl-control", janet_wrap_integer(CURLUSESSL_CONTROL), "ssl for the control connection or fail");
1626 | janet_def(env, "use-ssl-all", janet_wrap_integer(CURLUSESSL_ALL), "ssl for all communication or fail");
1627 |
1628 | // CURLOPT_FTPSSLAUTH
1629 | janet_def(env, "ftp-auth-default", janet_wrap_integer(CURLFTPAUTH_DEFAULT), "let libcurl decide");
1630 | janet_def(env, "ftp-auth-ssl", janet_wrap_integer(CURLFTPAUTH_SSL), "use auth ssl");
1631 | janet_def(env, "ftp-auth-tls", janet_wrap_integer(CURLFTPAUTH_TLS), "use auth tls");
1632 |
1633 | // CURLOPT_FTP_FILEMETHOD
1634 | janet_def(env, "ftp-method-default", janet_wrap_integer(CURLFTPMETHOD_DEFAULT), "let libcurl pick");
1635 | janet_def(env, "ftp-method-multicwd", janet_wrap_integer(CURLFTPMETHOD_MULTICWD), "single cwd operation for each path part");
1636 | janet_def(env, "ftp-method-nocwd", janet_wrap_integer(CURLFTPMETHOD_NOCWD), "no cwd at all");
1637 | janet_def(env, "ftp-method-singlecwd", janet_wrap_integer(CURLFTPMETHOD_SINGLECWD), "one cwd to full dir, then work on file");
1638 |
1639 | // CURLOPT_FTP_SSL_CCC
1640 | janet_def(env, "ftp-ssl-ccc-none", janet_wrap_integer(CURLFTPSSL_CCC_NONE), "do not send ccc");
1641 | janet_def(env, "ftp-ssl-ccc-passive", janet_wrap_integer(CURLFTPSSL_CCC_PASSIVE), "Let the server initiate the shutdown");
1642 | janet_def(env, "ftp-ssl-ccc-active", janet_wrap_integer(CURLFTPSSL_CCC_ACTIVE), "Initiate the shutdown");
1643 |
1644 | // CURLOPT_RTSP_REQUEST
1645 | janet_def(env, "rtsp-req-none", janet_wrap_integer(CURL_RTSPREQ_NONE), "//TODO: no description");
1646 | janet_def(env, "rtsp-req-options", janet_wrap_integer(CURL_RTSPREQ_OPTIONS), "//TODO: no description");
1647 | janet_def(env, "rtsp-req-describe", janet_wrap_integer(CURL_RTSPREQ_DESCRIBE), "//TODO: no description");
1648 | janet_def(env, "rtsp-req-announce", janet_wrap_integer(CURL_RTSPREQ_ANNOUNCE), "//TODO: no description");
1649 | janet_def(env, "rtsp-req-setup", janet_wrap_integer(CURL_RTSPREQ_SETUP), "//TODO: no description");
1650 | janet_def(env, "rtsp-req-play", janet_wrap_integer(CURL_RTSPREQ_PLAY), "//TODO: no description");
1651 | janet_def(env, "rtsp-req-pause", janet_wrap_integer(CURL_RTSPREQ_PAUSE), "//TODO: no description");
1652 | janet_def(env, "rtsp-req-teardown", janet_wrap_integer(CURL_RTSPREQ_TEARDOWN), "//TODO: no description");
1653 | janet_def(env, "rtsp-req-get-parameter", janet_wrap_integer(CURL_RTSPREQ_GET_PARAMETER), "//TODO: no description");
1654 | janet_def(env, "rtsp-req-set-parameter", janet_wrap_integer(CURL_RTSPREQ_SET_PARAMETER), "//TODO: no description");
1655 | janet_def(env, "rtsp-req-record", janet_wrap_integer(CURL_RTSPREQ_RECORD), "//TODO: no description");
1656 | janet_def(env, "rtsp-req-receive", janet_wrap_integer(CURL_RTSPREQ_RECEIVE), "//TODO: no description");
1657 |
1658 | // CURLOPT_GSSAPI_DELEGATION
1659 | janet_def(env, "gss-api-delegation-none", janet_wrap_integer(CURLGSSAPI_DELEGATION_NONE), "no delegation (default)");
1660 | janet_def(env, "gss-api-delegation-policy-flag", janet_wrap_integer(CURLGSSAPI_DELEGATION_POLICY_FLAG), "if permitted by policy");
1661 | janet_def(env, "gss-api-delegation-flag", janet_wrap_integer(CURLGSSAPI_DELEGATION_FLAG), "delegate always");
1662 |
1663 | // CURLOPT_PROXY_SSL_VERIFYHOST
1664 | janet_def(env, "proxy-ssl-verifyhost-no", janet_wrap_integer(0), "do not verify");
1665 | janet_def(env, "proxy-ssl-verifyhost-yes", janet_wrap_integer(2), "do not verify");
1666 |
1667 | // CURLOPT_PROXY_SSLVERSION
1668 | janet_def(env, "ssl-version-default", janet_wrap_integer(CURL_SSLVERSION_DEFAULT), "default");
1669 | janet_def(env, "ssl-version-tls-1", janet_wrap_integer(CURL_SSLVERSION_TLSv1), "tls 1");
1670 | janet_def(env, "ssl-version-ssl-2", janet_wrap_integer(CURL_SSLVERSION_SSLv2), "ssl 2");
1671 | janet_def(env, "ssl-version-ssl-3", janet_wrap_integer(CURL_SSLVERSION_SSLv3), "ssl 3");
1672 | janet_def(env, "ssl-version-tls-1.0", janet_wrap_integer(CURL_SSLVERSION_TLSv1_0), "tls 1.0");
1673 | janet_def(env, "ssl-version-tls-1.1", janet_wrap_integer(CURL_SSLVERSION_TLSv1_1), "tls 1.1");
1674 | janet_def(env, "ssl-version-tls-1.2", janet_wrap_integer(CURL_SSLVERSION_TLSv1_2), "tls 1.2");
1675 | janet_def(env, "ssl-version-tls-1.3", janet_wrap_integer(CURL_SSLVERSION_TLSv1_3), "tls 1.3");
1676 |
1677 | // CURLOPT_NETRC
1678 | janet_def(env, "netrc-ignored", janet_wrap_integer(CURL_NETRC_IGNORED), "ignored");
1679 | janet_def(env, "netrc-optional", janet_wrap_integer(CURL_NETRC_OPTIONAL), "optional");
1680 | janet_def(env, "netrc-required", janet_wrap_integer(CURL_NETRC_REQUIRED), "required");
1681 |
1682 |
1683 | janet_def(env, "url-part-url", janet_wrap_integer(CURLUPART_URL), "url part of url");
1684 | janet_def(env, "url-part-scheme", janet_wrap_integer(CURLUPART_SCHEME), "scheme part of url");
1685 | janet_def(env, "url-part-user", janet_wrap_integer(CURLUPART_USER), "user part of url");
1686 | janet_def(env, "url-part-password", janet_wrap_integer(CURLUPART_PASSWORD), "password part of url");
1687 | janet_def(env, "url-part-options", janet_wrap_integer(CURLUPART_OPTIONS), "options part of url");
1688 | janet_def(env, "url-part-host", janet_wrap_integer(CURLUPART_HOST), "host part of url");
1689 | janet_def(env, "url-part-port", janet_wrap_integer(CURLUPART_PORT), "port part of url");
1690 | janet_def(env, "url-part-path", janet_wrap_integer(CURLUPART_PATH), "path part of url");
1691 | janet_def(env, "url-part-query", janet_wrap_integer(CURLUPART_QUERY), "query part of url");
1692 | janet_def(env, "url-part-fragment", janet_wrap_integer(CURLUPART_FRAGMENT), "fragment part of url");
1693 |
1694 | // QUERY
1695 | janet_def(env, "query-none", janet_wrap_integer(CURLINFO_NONE), "query none");
1696 | janet_def(env, "query-effective-url", janet_wrap_integer(CURLINFO_EFFECTIVE_URL), "query effective-url");
1697 | janet_def(env, "query-response-code", janet_wrap_integer(CURLINFO_RESPONSE_CODE), "query response-code");
1698 | janet_def(env, "query-total-time", janet_wrap_integer(CURLINFO_TOTAL_TIME), "query total-time");
1699 | janet_def(env, "query-name-lookup-time", janet_wrap_integer(CURLINFO_NAMELOOKUP_TIME), "query namelookup-time");
1700 | janet_def(env, "query-connect-time", janet_wrap_integer(CURLINFO_CONNECT_TIME), "query connect-time");
1701 | janet_def(env, "query-pre-transfer-time", janet_wrap_integer(CURLINFO_PRETRANSFER_TIME), "query pretransfer-time");
1702 | janet_def(env, "query-size-upload", janet_wrap_integer(CURLINFO_SIZE_UPLOAD), "query size-upload");
1703 | janet_def(env, "query-size-upload-t", janet_wrap_integer(CURLINFO_SIZE_UPLOAD_T), "query size-upload-t");
1704 | janet_def(env, "query-size-download", janet_wrap_integer(CURLINFO_SIZE_DOWNLOAD), "query size-download");
1705 | janet_def(env, "query-size-download-t", janet_wrap_integer(CURLINFO_SIZE_DOWNLOAD_T), "query size-download-t");
1706 | janet_def(env, "query-speed-download", janet_wrap_integer(CURLINFO_SPEED_DOWNLOAD), "query speed-download");
1707 | janet_def(env, "query-speed-download-t", janet_wrap_integer(CURLINFO_SPEED_DOWNLOAD_T), "query speed-download-t");
1708 | janet_def(env, "query-speed-upload", janet_wrap_integer(CURLINFO_SPEED_UPLOAD), "query speed-upload");
1709 | janet_def(env, "query-speed-upload-t", janet_wrap_integer(CURLINFO_SPEED_UPLOAD_T), "query speed-upload-t");
1710 | janet_def(env, "query-header-size", janet_wrap_integer(CURLINFO_HEADER_SIZE), "query header-size");
1711 | janet_def(env, "query-request-size", janet_wrap_integer(CURLINFO_REQUEST_SIZE), "query request-size");
1712 | janet_def(env, "query-ssl-verify-result", janet_wrap_integer(CURLINFO_SSL_VERIFYRESULT), "query ssl-verifyresult");
1713 | janet_def(env, "query-file-time", janet_wrap_integer(CURLINFO_FILETIME), "query filetime");
1714 | janet_def(env, "query-file-time-t", janet_wrap_integer(CURLINFO_FILETIME_T), "query filetime-t");
1715 | janet_def(env, "query-content-length-download", janet_wrap_integer(CURLINFO_CONTENT_LENGTH_DOWNLOAD), "query content-length-download");
1716 | janet_def(env, "query-content-length-download-t", janet_wrap_integer(CURLINFO_CONTENT_LENGTH_DOWNLOAD_T), "query content-length-download-t");
1717 | janet_def(env, "query-content-length-upload", janet_wrap_integer(CURLINFO_CONTENT_LENGTH_UPLOAD), "query content-length-upload");
1718 | janet_def(env, "query-content-length-upload-t", janet_wrap_integer(CURLINFO_CONTENT_LENGTH_UPLOAD_T), "query content-length-upload-t");
1719 | janet_def(env, "query-start-transfer-time", janet_wrap_integer(CURLINFO_STARTTRANSFER_TIME), "query starttransfer-time");
1720 | janet_def(env, "query-content-type", janet_wrap_integer(CURLINFO_CONTENT_TYPE), "query content-type");
1721 | janet_def(env, "query-redirect-time", janet_wrap_integer(CURLINFO_REDIRECT_TIME), "query redirect-time");
1722 | janet_def(env, "query-redirect-count", janet_wrap_integer(CURLINFO_REDIRECT_COUNT), "query redirect-count");
1723 | janet_def(env, "query-private", janet_wrap_integer(CURLINFO_PRIVATE), "query private");
1724 | janet_def(env, "query-http-connect-code", janet_wrap_integer(CURLINFO_HTTP_CONNECTCODE), "query http-connectcode");
1725 | janet_def(env, "query-http-auth-avail", janet_wrap_integer(CURLINFO_HTTPAUTH_AVAIL), "query httpauth-avail");
1726 | janet_def(env, "query-proxy-auth-avail", janet_wrap_integer(CURLINFO_PROXYAUTH_AVAIL), "query proxyauth-avail");
1727 | janet_def(env, "query-os-errno", janet_wrap_integer(CURLINFO_OS_ERRNO), "query os-errno");
1728 | janet_def(env, "query-num-connects", janet_wrap_integer(CURLINFO_NUM_CONNECTS), "query num-connects");
1729 | janet_def(env, "query-ssl-engines", janet_wrap_integer(CURLINFO_SSL_ENGINES), "query ssl-engines");
1730 | janet_def(env, "query-cookie-list", janet_wrap_integer(CURLINFO_COOKIELIST), "query cookielist");
1731 | janet_def(env, "query-last-socket", janet_wrap_integer(CURLINFO_LASTSOCKET), "query lastsocket");
1732 | janet_def(env, "query-ftp-entry-path", janet_wrap_integer(CURLINFO_FTP_ENTRY_PATH), "query ftp-entry-path");
1733 | janet_def(env, "query-redirect-url", janet_wrap_integer(CURLINFO_REDIRECT_URL), "query redirect-url");
1734 | janet_def(env, "query-primary-ip", janet_wrap_integer(CURLINFO_PRIMARY_IP), "query primary-ip");
1735 | janet_def(env, "query-app-connect-time", janet_wrap_integer(CURLINFO_APPCONNECT_TIME), "query appconnect-time");
1736 | janet_def(env, "query-cert-info", janet_wrap_integer(CURLINFO_CERTINFO), "query certinfo");
1737 | janet_def(env, "query-condition-unmet", janet_wrap_integer(CURLINFO_CONDITION_UNMET), "query condition-unmet");
1738 | janet_def(env, "query-rtsp-session-id", janet_wrap_integer(CURLINFO_RTSP_SESSION_ID), "query rtsp-session-id");
1739 | janet_def(env, "query-rtsp-client-cseq", janet_wrap_integer(CURLINFO_RTSP_CLIENT_CSEQ), "query rtsp-client-cseq");
1740 | janet_def(env, "query-rtsp-server-cseq", janet_wrap_integer(CURLINFO_RTSP_SERVER_CSEQ), "query rtsp-server-cseq");
1741 | janet_def(env, "query-rtsp-cseq-recv", janet_wrap_integer(CURLINFO_RTSP_CSEQ_RECV), "query rtsp-cseq-recv");
1742 | janet_def(env, "query-primary-port", janet_wrap_integer(CURLINFO_PRIMARY_PORT), "query primary-port");
1743 | janet_def(env, "query-local-ip", janet_wrap_integer(CURLINFO_LOCAL_IP), "query local-ip");
1744 | janet_def(env, "query-local-port", janet_wrap_integer(CURLINFO_LOCAL_PORT), "query local-port");
1745 | janet_def(env, "query-tls-session", janet_wrap_integer(CURLINFO_TLS_SESSION), "query tls-session");
1746 | janet_def(env, "query-active-socket", janet_wrap_integer(CURLINFO_ACTIVESOCKET), "query activesocket");
1747 | janet_def(env, "query-tls-ssl-ptr", janet_wrap_integer(CURLINFO_TLS_SSL_PTR), "query tls-ssl-ptr");
1748 | janet_def(env, "query-http-version", janet_wrap_integer(CURLINFO_HTTP_VERSION), "query http-version");
1749 | janet_def(env, "query-proxy-ssl-verify-result", janet_wrap_integer(CURLINFO_PROXY_SSL_VERIFYRESULT), "query proxy-ssl-verifyresult");
1750 | janet_def(env, "query-protocol", janet_wrap_integer(CURLINFO_PROTOCOL), "query protocol");
1751 | janet_def(env, "query-scheme", janet_wrap_integer(CURLINFO_SCHEME), "query scheme");
1752 | janet_def(env, "query-total-time-t", janet_wrap_integer(CURLINFO_TOTAL_TIME_T), "query total-time-t");
1753 | janet_def(env, "query-name-lookup-time-t", janet_wrap_integer(CURLINFO_NAMELOOKUP_TIME_T), "query namelookup-time-t");
1754 | janet_def(env, "query-connect-time-t", janet_wrap_integer(CURLINFO_CONNECT_TIME_T), "query connect-time-t");
1755 | janet_def(env, "query-pre-transfer-time-t", janet_wrap_integer(CURLINFO_PRETRANSFER_TIME_T), "query pretransfer-time-t");
1756 | janet_def(env, "query-start-transfer-time-t", janet_wrap_integer(CURLINFO_STARTTRANSFER_TIME_T), "query starttransfer-time-t");
1757 | janet_def(env, "query-redirect-time-t", janet_wrap_integer(CURLINFO_REDIRECT_TIME_T), "query redirect-time-t");
1758 | janet_def(env, "query-app-connect-time-t", janet_wrap_integer(CURLINFO_APPCONNECT_TIME_T), "query appconnect-time-t");
1759 |
1760 | // .:MASK:.
1761 | // CURLOPT_SSH_AUTH_TYPES
1762 | janet_def(env, "ssh-auth-any", janet_wrap_integer(CURLSSH_AUTH_ANY), "any (bitmask)");
1763 | janet_def(env, "ssh-auth-none", janet_wrap_integer(CURLSSH_AUTH_NONE), "none (bitmask)");
1764 | janet_def(env, "ssh-auth-public-key", janet_wrap_integer(CURLSSH_AUTH_PUBLICKEY), "public key (bitmask)");
1765 | janet_def(env, "ssh-auth-password", janet_wrap_integer(CURLSSH_AUTH_PASSWORD), "password (bitmask)");
1766 | janet_def(env, "ssh-auth-host", janet_wrap_integer(CURLSSH_AUTH_HOST), "host (bitmask)");
1767 | janet_def(env, "ssh-auth-keyboard", janet_wrap_integer(CURLSSH_AUTH_KEYBOARD), "keyboard (bitmask)");
1768 | janet_def(env, "ssh-auth-agent", janet_wrap_integer(CURLSSH_AUTH_AGENT), "agent (bitmask)");
1769 | janet_def(env, "ssh-auth-gss-api", janet_wrap_integer(CURLSSH_AUTH_GSSAPI), "gss api (bitmask)");
1770 | janet_def(env, "ssh-auth-default", janet_wrap_integer(CURLSSH_AUTH_DEFAULT), "default (bitmask)");
1771 |
1772 | // CURLOPT_POSTREDIR
1773 | janet_def(env, "redir-get-all", janet_wrap_integer(CURL_REDIR_GET_ALL), "get all (bitmask)");
1774 | janet_def(env, "redir-post-301", janet_wrap_integer(CURL_REDIR_POST_301), "post 301 (bitmask)");
1775 | janet_def(env, "redir-post-302", janet_wrap_integer(CURL_REDIR_POST_302), "post 302 (bitmask)");
1776 | janet_def(env, "redir-post-303", janet_wrap_integer(CURL_REDIR_POST_303), "post 303 (bitmask)");
1777 | janet_def(env, "redir-post-all", janet_wrap_integer(CURL_REDIR_POST_ALL), "post all (bitmask)");
1778 |
1779 | // CURLOPT_PROTOCOLS
1780 | janet_def(env, "proto-http", janet_wrap_integer(CURLPROTO_HTTP), "http (bitmask)");
1781 | janet_def(env, "proto-https", janet_wrap_integer(CURLPROTO_HTTPS), "https (bitmask)");
1782 | janet_def(env, "proto-ftp", janet_wrap_integer(CURLPROTO_FTP), "ftp (bitmask)");
1783 | janet_def(env, "proto-ftps", janet_wrap_integer(CURLPROTO_FTPS), "ftps (bitmask)");
1784 | janet_def(env, "proto-scp", janet_wrap_integer(CURLPROTO_SCP), "scp (bitmask)");
1785 | janet_def(env, "proto-sftp", janet_wrap_integer(CURLPROTO_SFTP), "sftp (bitmask)");
1786 | janet_def(env, "proto-telnet", janet_wrap_integer(CURLPROTO_TELNET), "telnet (bitmask)");
1787 | janet_def(env, "proto-ldap", janet_wrap_integer(CURLPROTO_LDAP), "ldap (bitmask)");
1788 | janet_def(env, "proto-ldaps", janet_wrap_integer(CURLPROTO_LDAPS), "ldaps (bitmask)");
1789 | janet_def(env, "proto-dict", janet_wrap_integer(CURLPROTO_DICT), "dict (bitmask)");
1790 | janet_def(env, "proto-file", janet_wrap_integer(CURLPROTO_FILE), "file (bitmask)");
1791 | janet_def(env, "proto-tftp", janet_wrap_integer(CURLPROTO_TFTP), "tftp (bitmask)");
1792 | janet_def(env, "proto-imap", janet_wrap_integer(CURLPROTO_IMAP), "imap (bitmask)");
1793 | janet_def(env, "proto-imaps", janet_wrap_integer(CURLPROTO_IMAPS), "imaps (bitmask)");
1794 | janet_def(env, "proto-pop3", janet_wrap_integer(CURLPROTO_POP3), "pop3 (bitmask)");
1795 | janet_def(env, "proto-pop3s", janet_wrap_integer(CURLPROTO_POP3S), "pop3s (bitmask)");
1796 | janet_def(env, "proto-smtp", janet_wrap_integer(CURLPROTO_SMTP), "smtp (bitmask)");
1797 | janet_def(env, "proto-smtps", janet_wrap_integer(CURLPROTO_SMTPS), "smtps (bitmask)");
1798 | janet_def(env, "proto-rtsp", janet_wrap_integer(CURLPROTO_RTSP), "rtsp (bitmask)");
1799 | janet_def(env, "proto-rtmp", janet_wrap_integer(CURLPROTO_RTMP), "rtmp (bitmask)");
1800 | janet_def(env, "proto-rtmpt", janet_wrap_integer(CURLPROTO_RTMPT), "rtmpt (bitmask)");
1801 | janet_def(env, "proto-rtmpe", janet_wrap_integer(CURLPROTO_RTMPE), "rtmpe (bitmask)");
1802 | janet_def(env, "proto-rtmpte", janet_wrap_integer(CURLPROTO_RTMPTE), "rtmpte (bitmask)");
1803 | janet_def(env, "proto-rtmps", janet_wrap_integer(CURLPROTO_RTMPS), "rtmps (bitmask)");
1804 | janet_def(env, "proto-rtmpts", janet_wrap_integer(CURLPROTO_RTMPTS), "rtmpts (bitmask)");
1805 | janet_def(env, "proto-gopher", janet_wrap_integer(CURLPROTO_GOPHER), "gopher (bitmask)");
1806 | janet_def(env, "proto-smb", janet_wrap_integer(CURLPROTO_SMB), "smb (bitmask)");
1807 | janet_def(env, "proto-smbs", janet_wrap_integer(CURLPROTO_SMBS), "smbs (bitmask)");
1808 | janet_def(env, "proto-all", janet_wrap_integer(CURLPROTO_ALL), "all (bitmask)");
1809 |
1810 | // CURLOPT_REDIR_PROTOCOLS
1811 | janet_def(env, "re-dir-proto-http", janet_wrap_integer(CURLPROTO_HTTP), "http (bitmask)");
1812 | janet_def(env, "re-dir-proto-https", janet_wrap_integer(CURLPROTO_HTTPS), "https (bitmask)");
1813 | janet_def(env, "re-dir-proto-ftp", janet_wrap_integer(CURLPROTO_FTP), "ftp (bitmask)");
1814 | janet_def(env, "re-dir-proto-ftps", janet_wrap_integer(CURLPROTO_FTPS), "ftps (bitmask)");
1815 | janet_def(env, "re-dir-proto-scp", janet_wrap_integer(CURLPROTO_SCP), "scp (bitmask)");
1816 | janet_def(env, "re-dir-proto-sftp", janet_wrap_integer(CURLPROTO_SFTP), "sftp (bitmask)");
1817 | janet_def(env, "re-dir-proto-telnet", janet_wrap_integer(CURLPROTO_TELNET), "telnet (bitmask)");
1818 | janet_def(env, "re-dir-proto-ldap", janet_wrap_integer(CURLPROTO_LDAP), "ldap (bitmask)");
1819 | janet_def(env, "re-dir-proto-ldaps", janet_wrap_integer(CURLPROTO_LDAPS), "ldaps (bitmask)");
1820 | janet_def(env, "re-dir-proto-dict", janet_wrap_integer(CURLPROTO_DICT), "dict (bitmask)");
1821 | janet_def(env, "re-dir-proto-file", janet_wrap_integer(CURLPROTO_FILE), "file (bitmask)");
1822 | janet_def(env, "re-dir-proto-tftp", janet_wrap_integer(CURLPROTO_TFTP), "tftp (bitmask)");
1823 | janet_def(env, "re-dir-proto-imap", janet_wrap_integer(CURLPROTO_IMAP), "imap (bitmask)");
1824 | janet_def(env, "re-dir-proto-imaps", janet_wrap_integer(CURLPROTO_IMAPS), "imaps (bitmask)");
1825 | janet_def(env, "re-dir-proto-pop3", janet_wrap_integer(CURLPROTO_POP3), "pop3 (bitmask)");
1826 | janet_def(env, "re-dir-proto-pop3s", janet_wrap_integer(CURLPROTO_POP3S), "pop3s (bitmask)");
1827 | janet_def(env, "re-dir-proto-smtp", janet_wrap_integer(CURLPROTO_SMTP), "smtp (bitmask)");
1828 | janet_def(env, "re-dir-proto-smtps", janet_wrap_integer(CURLPROTO_SMTPS), "smtps (bitmask)");
1829 | janet_def(env, "re-dir-proto-rtsp", janet_wrap_integer(CURLPROTO_RTSP), "rtsp (bitmask)");
1830 | janet_def(env, "re-dir-proto-rtmp", janet_wrap_integer(CURLPROTO_RTMP), "rtmp (bitmask)");
1831 | janet_def(env, "re-dir-proto-rtmpt", janet_wrap_integer(CURLPROTO_RTMPT), "rtmpt (bitmask)");
1832 | janet_def(env, "re-dir-proto-rtmpe", janet_wrap_integer(CURLPROTO_RTMPE), "rtmpe (bitmask)");
1833 | janet_def(env, "re-dir-proto-rtmpte", janet_wrap_integer(CURLPROTO_RTMPTE), "rtmpte (bitmask)");
1834 | janet_def(env, "re-dir-proto-rtmps", janet_wrap_integer(CURLPROTO_RTMPS), "rtmps (bitmask)");
1835 | janet_def(env, "re-dir-proto-rtmpts", janet_wrap_integer(CURLPROTO_RTMPTS), "rtmpts (bitmask)");
1836 | janet_def(env, "re-dir-proto-gopher", janet_wrap_integer(CURLPROTO_GOPHER), "gopher (bitmask)");
1837 | janet_def(env, "re-dir-proto-smb", janet_wrap_integer(CURLPROTO_SMB), "smb (bitmask)");
1838 | janet_def(env, "re-dir-proto-smbs", janet_wrap_integer(CURLPROTO_SMBS), "smbs (bitmask)");
1839 | janet_def(env, "re-dir-proto-all", janet_wrap_integer(CURLPROTO_ALL), "all (bitmask)");
1840 |
1841 | // CURLOPT_SSL_OPTIONS
1842 | janet_def(env, "ssl-opt-allow", janet_wrap_integer(CURLSSLOPT_ALLOW_BEAST), "allow beast (bitmask)");
1843 | janet_def(env, "ssl-opt-no", janet_wrap_integer(CURLSSLOPT_NO_REVOKE), "no revoke (bitmask)");
1844 |
1845 | // CURLOPT_PROXY_SSL_OPTIONS
1846 | janet_def(env, "proxy-ssl-opt-allow", janet_wrap_integer(CURLSSLOPT_ALLOW_BEAST), "allow beast (bitmask)");
1847 | janet_def(env, "proxy-ssl-opt-no", janet_wrap_integer(CURLSSLOPT_NO_REVOKE), "no revoke (bitmask)");
1848 |
1849 | // CURLOPT_HEADEROPT
1850 | janet_def(env, "header-opt-unified", janet_wrap_integer(CURLHEADER_UNIFIED), "unified (bitmask)");
1851 | janet_def(env, "header-opt-separate", janet_wrap_integer(CURLHEADER_SEPARATE), "separate (bitmask)");
1852 |
1853 | // CURLOPT_HTTPAUTH
1854 | janet_def(env, "http-auth-none", janet_wrap_integer(CURLAUTH_NONE), "no authentication");
1855 | janet_def(env, "http-auth-basic", janet_wrap_integer(CURLAUTH_BASIC), "basic authentication type");
1856 | janet_def(env, "http-auth-digest", janet_wrap_integer(CURLAUTH_DIGEST), "digest authentication type");
1857 | janet_def(env, "http-auth-digest-ie", janet_wrap_integer(CURLAUTH_DIGEST_IE), "digest authentication type with IE flavor");
1858 | janet_def(env, "http-auth-negotiate", janet_wrap_integer(CURLAUTH_NEGOTIATE), "negotiate authentication type");
1859 | janet_def(env, "http-auth-gss-api", janet_wrap_integer(CURLAUTH_GSSAPI), "gss api authentication type");
1860 | janet_def(env, "http-auth-ntlm", janet_wrap_integer(CURLAUTH_NTLM), "ntlm authentication type");
1861 | janet_def(env, "http-auth-ntlm-wb", janet_wrap_integer(CURLAUTH_NTLM_WB), "ntlm wb authentication type");
1862 | janet_def(env, "http-auth-bearer", janet_wrap_integer(CURLAUTH_BEARER), "bearer authentication type");
1863 | janet_def(env, "http-auth-only", janet_wrap_integer(CURLAUTH_ONLY), "//TODO: how to handle this?");
1864 | janet_def(env, "http-auth-any", janet_wrap_integer(CURLAUTH_ANY), "any authentication type");
1865 | janet_def(env, "http-auth-any-safe", janet_wrap_integer(CURLAUTH_ANYSAFE), "any safe authentication type");
1866 | janet_def(env, "http-auth-aws-sigv4", janet_wrap_integer(CURLAUTH_AWS_SIGV4), "aws sigv4 authentication type");
1867 |
1868 | // CURLOPT_PROXYAUTH
1869 | janet_def(env, "proxy-none", janet_wrap_integer(CURLAUTH_NONE), "none");
1870 | janet_def(env, "proxy-basic", janet_wrap_integer(CURLAUTH_BASIC), "basic");
1871 | janet_def(env, "proxy-digest", janet_wrap_integer(CURLAUTH_DIGEST), "digest");
1872 | janet_def(env, "proxy-negotiate", janet_wrap_integer(CURLAUTH_NEGOTIATE), "negotiate");
1873 | janet_def(env, "proxy-gssapi", janet_wrap_integer(CURLAUTH_GSSAPI), "gssapi");
1874 | janet_def(env, "proxy-ntlm", janet_wrap_integer(CURLAUTH_NTLM), "ntlm");
1875 | janet_def(env, "proxy-digest-ie", janet_wrap_integer(CURLAUTH_DIGEST_IE), "digest-ie");
1876 | janet_def(env, "proxy-ntlm-wb", janet_wrap_integer(CURLAUTH_NTLM_WB), "ntlm-wb");
1877 | janet_def(env, "proxy-bearer", janet_wrap_integer(CURLAUTH_BEARER), "bearer");
1878 | janet_def(env, "proxy-only", janet_wrap_integer(CURLAUTH_ONLY), "only");
1879 | janet_def(env, "proxy-any", janet_wrap_integer(CURLAUTH_ANY), "any");
1880 | janet_def(env, "proxy-anysafe", janet_wrap_integer(CURLAUTH_ANYSAFE), "anysafe");
1881 |
1882 | // CURLOPT_SOCKS5_AUTH
1883 | janet_def(env, "sock5-auth-none", janet_wrap_integer(CURLAUTH_NONE), "no authentication (bitmask)");
1884 | janet_def(env, "sock5-auth-basic", janet_wrap_integer(CURLAUTH_BASIC), "basic authentication type (bitmask)");
1885 | janet_def(env, "sock5-auth-digest", janet_wrap_integer(CURLAUTH_DIGEST), "digest authentication type (bitmask)");
1886 | janet_def(env, "sock5-auth-digest-ie", janet_wrap_integer(CURLAUTH_DIGEST_IE), "digest authentication type with IE flavor (bitmask)");
1887 | janet_def(env, "sock5-auth-negotiate", janet_wrap_integer(CURLAUTH_NEGOTIATE), "negotiate authentication type (bitmask)");
1888 | janet_def(env, "sock5-auth-gss-api", janet_wrap_integer(CURLAUTH_GSSAPI), "gss api authentication type (bitmask)");
1889 | janet_def(env, "sock5-auth-ntlm", janet_wrap_integer(CURLAUTH_NTLM), "ntlm authentication type (bitmask)");
1890 | janet_def(env, "sock5-auth-ntlm-wb", janet_wrap_integer(CURLAUTH_NTLM_WB), "ntlm wb authentication type (bitmask)");
1891 | janet_def(env, "sock5-auth-bearer", janet_wrap_integer(CURLAUTH_BEARER), "bearer authentication type (bitmask)");
1892 | janet_def(env, "sock5-auth-only", janet_wrap_integer(CURLAUTH_ONLY), "//TODO: how to handle this? (bitmask)");
1893 | janet_def(env, "sock5-auth-any", janet_wrap_integer(CURLAUTH_ANY), "any authentication type (bitmask)");
1894 | janet_def(env, "sock5-auth-any-safe", janet_wrap_integer(CURLAUTH_ANYSAFE), "any safe authentication type (bitmask)");
1895 |
1896 | // CURLU_EXTRACT_FLAGS
1897 | janet_def(env, "url-extract-flag-default-port", janet_wrap_integer(CURLU_DEFAULT_PORT), "default port (bitmask)");
1898 | janet_def(env, "url-extract-flag-no-default-port", janet_wrap_integer(CURLU_NO_DEFAULT_PORT), "no default port (bitmask)");
1899 | janet_def(env, "url-extract-flag-default-scheme", janet_wrap_integer(CURLU_DEFAULT_SCHEME), "default scheme (bitmask)");
1900 | janet_def(env, "url-extract-flag-non-support-scheme", janet_wrap_integer(CURLU_NON_SUPPORT_SCHEME), "non support scheme (bitmask)");
1901 | janet_def(env, "url-extract-flag-path-as-is", janet_wrap_integer(CURLU_PATH_AS_IS), "path as is (bitmask)");
1902 | janet_def(env, "url-extract-flag-disallow-user", janet_wrap_integer(CURLU_DISALLOW_USER), "disallow user (bitmask)");
1903 | janet_def(env, "url-extract-flag-url-decode", janet_wrap_integer(CURLU_URLDECODE), "url decode (bitmask)");
1904 | janet_def(env, "url-extract-flag-url-encode", janet_wrap_integer(CURLU_URLENCODE), "url encode (bitmask)");
1905 | janet_def(env, "url-extract-flag-append-query", janet_wrap_integer(CURLU_APPENDQUERY), "append query (bitmask)");
1906 | janet_def(env, "url-extract-flag-guess-scheme", janet_wrap_integer(CURLU_GUESS_SCHEME), "guess scheme (bitmask)");
1907 |
1908 | // submodules
1909 | submod_easy(env);
1910 | submod_share(env);
1911 | submod_url(env);
1912 | submod_mime(env);
1913 | }
1914 |
--------------------------------------------------------------------------------
/src/khash.h:
--------------------------------------------------------------------------------
1 | /* The MIT License
2 |
3 | Copyright (c) 2008, 2009, 2011 by Attractive Chaos
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | "Software"), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be
14 | included in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | SOFTWARE.
24 | */
25 |
26 | /*
27 | An example:
28 |
29 | #include "khash.h"
30 | KHASH_MAP_INIT_INT(32, char)
31 | int main() {
32 | int ret, is_missing;
33 | khiter_t k;
34 | khash_t(32) *h = kh_init(32);
35 | k = kh_put(32, h, 5, &ret);
36 | kh_value(h, k) = 10;
37 | k = kh_get(32, h, 10);
38 | is_missing = (k == kh_end(h));
39 | k = kh_get(32, h, 5);
40 | kh_del(32, h, k);
41 | for (k = kh_begin(h); k != kh_end(h); ++k)
42 | if (kh_exist(h, k)) kh_value(h, k) = 1;
43 | kh_destroy(32, h);
44 | return 0;
45 | }
46 | */
47 |
48 | /*
49 | 2013-05-02 (0.2.8):
50 |
51 | * Use quadratic probing. When the capacity is power of 2, stepping function
52 | i*(i+1)/2 guarantees to traverse each bucket. It is better than double
53 | hashing on cache performance and is more robust than linear probing.
54 |
55 | In theory, double hashing should be more robust than quadratic probing.
56 | However, my implementation is probably not for large hash tables, because
57 | the second hash function is closely tied to the first hash function,
58 | which reduce the effectiveness of double hashing.
59 |
60 | Reference: http://research.cs.vt.edu/AVresearch/hashing/quadratic.php
61 |
62 | 2011-12-29 (0.2.7):
63 |
64 | * Minor code clean up; no actual effect.
65 |
66 | 2011-09-16 (0.2.6):
67 |
68 | * The capacity is a power of 2. This seems to dramatically improve the
69 | speed for simple keys. Thank Zilong Tan for the suggestion. Reference:
70 |
71 | - http://code.google.com/p/ulib/
72 | - http://nothings.org/computer/judy/
73 |
74 | * Allow to optionally use linear probing which usually has better
75 | performance for random input. Double hashing is still the default as it
76 | is more robust to certain non-random input.
77 |
78 | * Added Wang's integer hash function (not used by default). This hash
79 | function is more robust to certain non-random input.
80 |
81 | 2011-02-14 (0.2.5):
82 |
83 | * Allow to declare global functions.
84 |
85 | 2009-09-26 (0.2.4):
86 |
87 | * Improve portability
88 |
89 | 2008-09-19 (0.2.3):
90 |
91 | * Corrected the example
92 | * Improved interfaces
93 |
94 | 2008-09-11 (0.2.2):
95 |
96 | * Improved speed a little in kh_put()
97 |
98 | 2008-09-10 (0.2.1):
99 |
100 | * Added kh_clear()
101 | * Fixed a compiling error
102 |
103 | 2008-09-02 (0.2.0):
104 |
105 | * Changed to token concatenation which increases flexibility.
106 |
107 | 2008-08-31 (0.1.2):
108 |
109 | * Fixed a bug in kh_get(), which has not been tested previously.
110 |
111 | 2008-08-31 (0.1.1):
112 |
113 | * Added destructor
114 | */
115 |
116 |
117 | #ifndef __AC_KHASH_H
118 | #define __AC_KHASH_H
119 |
120 | /*!
121 | @header
122 |
123 | Generic hash table library.
124 | */
125 |
126 | #define AC_VERSION_KHASH_H "0.2.8"
127 |
128 | #include
129 | #include
130 | #include
131 |
132 | /* compiler specific configuration */
133 |
134 | #if UINT_MAX == 0xffffffffu
135 | typedef unsigned int khint32_t;
136 | #elif ULONG_MAX == 0xffffffffu
137 | typedef unsigned long khint32_t;
138 | #endif
139 |
140 | #if ULONG_MAX == ULLONG_MAX
141 | typedef unsigned long khint64_t;
142 | #else
143 | typedef unsigned long long khint64_t;
144 | #endif
145 |
146 | #ifndef kh_inline
147 | #ifdef _MSC_VER
148 | #define kh_inline __inline
149 | #else
150 | #define kh_inline inline
151 | #endif
152 | #endif /* kh_inline */
153 |
154 | #ifndef klib_unused
155 | #if (defined __clang__ && __clang_major__ >= 3) || (defined __GNUC__ && __GNUC__ >= 3)
156 | #define klib_unused __attribute__ ((__unused__))
157 | #else
158 | #define klib_unused
159 | #endif
160 | #endif /* klib_unused */
161 |
162 | typedef khint32_t khint_t;
163 | typedef khint_t khiter_t;
164 |
165 | #define __ac_isempty(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&2)
166 | #define __ac_isdel(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&1)
167 | #define __ac_iseither(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&3)
168 | #define __ac_set_isdel_false(flag, i) (flag[i>>4]&=~(1ul<<((i&0xfU)<<1)))
169 | #define __ac_set_isempty_false(flag, i) (flag[i>>4]&=~(2ul<<((i&0xfU)<<1)))
170 | #define __ac_set_isboth_false(flag, i) (flag[i>>4]&=~(3ul<<((i&0xfU)<<1)))
171 | #define __ac_set_isdel_true(flag, i) (flag[i>>4]|=1ul<<((i&0xfU)<<1))
172 |
173 | #define __ac_fsize(m) ((m) < 16? 1 : (m)>>4)
174 |
175 | #ifndef kroundup32
176 | #define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
177 | #endif
178 |
179 | #ifndef kcalloc
180 | #define kcalloc(N,Z) calloc(N,Z)
181 | #endif
182 | #ifndef kmalloc
183 | #define kmalloc(Z) malloc(Z)
184 | #endif
185 | #ifndef krealloc
186 | #define krealloc(P,Z) realloc(P,Z)
187 | #endif
188 | #ifndef kfree
189 | #define kfree(P) free(P)
190 | #endif
191 |
192 | static const double __ac_HASH_UPPER = 0.77;
193 |
194 | #define __KHASH_TYPE(name, khkey_t, khval_t) \
195 | typedef struct kh_##name##_s { \
196 | khint_t n_buckets, size, n_occupied, upper_bound; \
197 | khint32_t *flags; \
198 | khkey_t *keys; \
199 | khval_t *vals; \
200 | } kh_##name##_t;
201 |
202 | #define __KHASH_PROTOTYPES(name, khkey_t, khval_t) \
203 | extern kh_##name##_t *kh_init_##name(void); \
204 | extern void kh_destroy_##name(kh_##name##_t *h); \
205 | extern void kh_clear_##name(kh_##name##_t *h); \
206 | extern khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key); \
207 | extern int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \
208 | extern khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret); \
209 | extern void kh_del_##name(kh_##name##_t *h, khint_t x);
210 |
211 | #define __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
212 | SCOPE kh_##name##_t *kh_init_##name(void) { \
213 | return (kh_##name##_t*)kcalloc(1, sizeof(kh_##name##_t)); \
214 | } \
215 | SCOPE void kh_destroy_##name(kh_##name##_t *h) \
216 | { \
217 | if (h) { \
218 | kfree((void *)h->keys); kfree(h->flags); \
219 | kfree((void *)h->vals); \
220 | kfree(h); \
221 | } \
222 | } \
223 | SCOPE void kh_clear_##name(kh_##name##_t *h) \
224 | { \
225 | if (h && h->flags) { \
226 | memset(h->flags, 0xaa, __ac_fsize(h->n_buckets) * sizeof(khint32_t)); \
227 | h->size = h->n_occupied = 0; \
228 | } \
229 | } \
230 | SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \
231 | { \
232 | if (h->n_buckets) { \
233 | khint_t k, i, last, mask, step = 0; \
234 | mask = h->n_buckets - 1; \
235 | k = __hash_func(key); i = k & mask; \
236 | last = i; \
237 | while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \
238 | i = (i + (++step)) & mask; \
239 | if (i == last) return h->n_buckets; \
240 | } \
241 | return __ac_iseither(h->flags, i)? h->n_buckets : i; \
242 | } else return 0; \
243 | } \
244 | SCOPE int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \
245 | { /* This function uses 0.25*n_buckets bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. */ \
246 | khint32_t *new_flags = 0; \
247 | khint_t j = 1; \
248 | { \
249 | kroundup32(new_n_buckets); \
250 | if (new_n_buckets < 4) new_n_buckets = 4; \
251 | if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) j = 0; /* requested size is too small */ \
252 | else { /* hash table size to be changed (shrink or expand); rehash */ \
253 | new_flags = (khint32_t*)kmalloc(__ac_fsize(new_n_buckets) * sizeof(khint32_t)); \
254 | if (!new_flags) return -1; \
255 | memset(new_flags, 0xaa, __ac_fsize(new_n_buckets) * sizeof(khint32_t)); \
256 | if (h->n_buckets < new_n_buckets) { /* expand */ \
257 | khkey_t *new_keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \
258 | if (!new_keys) { kfree(new_flags); return -1; } \
259 | h->keys = new_keys; \
260 | if (kh_is_map) { \
261 | khval_t *new_vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \
262 | if (!new_vals) { kfree(new_flags); return -1; } \
263 | h->vals = new_vals; \
264 | } \
265 | } /* otherwise shrink */ \
266 | } \
267 | } \
268 | if (j) { /* rehashing is needed */ \
269 | for (j = 0; j != h->n_buckets; ++j) { \
270 | if (__ac_iseither(h->flags, j) == 0) { \
271 | khkey_t key = h->keys[j]; \
272 | khval_t val; \
273 | khint_t new_mask; \
274 | new_mask = new_n_buckets - 1; \
275 | if (kh_is_map) val = h->vals[j]; \
276 | __ac_set_isdel_true(h->flags, j); \
277 | while (1) { /* kick-out process; sort of like in Cuckoo hashing */ \
278 | khint_t k, i, step = 0; \
279 | k = __hash_func(key); \
280 | i = k & new_mask; \
281 | while (!__ac_isempty(new_flags, i)) i = (i + (++step)) & new_mask; \
282 | __ac_set_isempty_false(new_flags, i); \
283 | if (i < h->n_buckets && __ac_iseither(h->flags, i) == 0) { /* kick out the existing element */ \
284 | { khkey_t tmp = h->keys[i]; h->keys[i] = key; key = tmp; } \
285 | if (kh_is_map) { khval_t tmp = h->vals[i]; h->vals[i] = val; val = tmp; } \
286 | __ac_set_isdel_true(h->flags, i); /* mark it as deleted in the old hash table */ \
287 | } else { /* write the element and jump out of the loop */ \
288 | h->keys[i] = key; \
289 | if (kh_is_map) h->vals[i] = val; \
290 | break; \
291 | } \
292 | } \
293 | } \
294 | } \
295 | if (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \
296 | h->keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \
297 | if (kh_is_map) h->vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \
298 | } \
299 | kfree(h->flags); /* free the working space */ \
300 | h->flags = new_flags; \
301 | h->n_buckets = new_n_buckets; \
302 | h->n_occupied = h->size; \
303 | h->upper_bound = (khint_t)(h->n_buckets * __ac_HASH_UPPER + 0.5); \
304 | } \
305 | return 0; \
306 | } \
307 | SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \
308 | { \
309 | khint_t x; \
310 | if (h->n_occupied >= h->upper_bound) { /* update the hash table */ \
311 | if (h->n_buckets > (h->size<<1)) { \
312 | if (kh_resize_##name(h, h->n_buckets - 1) < 0) { /* clear "deleted" elements */ \
313 | *ret = -1; return h->n_buckets; \
314 | } \
315 | } else if (kh_resize_##name(h, h->n_buckets + 1) < 0) { /* expand the hash table */ \
316 | *ret = -1; return h->n_buckets; \
317 | } \
318 | } /* TODO: to implement automatically shrinking; resize() already support shrinking */ \
319 | { \
320 | khint_t k, i, site, last, mask = h->n_buckets - 1, step = 0; \
321 | x = site = h->n_buckets; k = __hash_func(key); i = k & mask; \
322 | if (__ac_isempty(h->flags, i)) x = i; /* for speed up */ \
323 | else { \
324 | last = i; \
325 | while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \
326 | if (__ac_isdel(h->flags, i)) site = i; \
327 | i = (i + (++step)) & mask; \
328 | if (i == last) { x = site; break; } \
329 | } \
330 | if (x == h->n_buckets) { \
331 | if (__ac_isempty(h->flags, i) && site != h->n_buckets) x = site; \
332 | else x = i; \
333 | } \
334 | } \
335 | } \
336 | if (__ac_isempty(h->flags, x)) { /* not present at all */ \
337 | h->keys[x] = key; \
338 | __ac_set_isboth_false(h->flags, x); \
339 | ++h->size; ++h->n_occupied; \
340 | *ret = 1; \
341 | } else if (__ac_isdel(h->flags, x)) { /* deleted */ \
342 | h->keys[x] = key; \
343 | __ac_set_isboth_false(h->flags, x); \
344 | ++h->size; \
345 | *ret = 2; \
346 | } else *ret = 0; /* Don't touch h->keys[x] if present and not deleted */ \
347 | return x; \
348 | } \
349 | SCOPE void kh_del_##name(kh_##name##_t *h, khint_t x) \
350 | { \
351 | if (x != h->n_buckets && !__ac_iseither(h->flags, x)) { \
352 | __ac_set_isdel_true(h->flags, x); \
353 | --h->size; \
354 | } \
355 | }
356 |
357 | #define KHASH_DECLARE(name, khkey_t, khval_t) \
358 | __KHASH_TYPE(name, khkey_t, khval_t) \
359 | __KHASH_PROTOTYPES(name, khkey_t, khval_t)
360 |
361 | #define KHASH_INIT2(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
362 | __KHASH_TYPE(name, khkey_t, khval_t) \
363 | __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal)
364 |
365 | #define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
366 | KHASH_INIT2(name, static kh_inline klib_unused, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal)
367 |
368 | /* --- BEGIN OF HASH FUNCTIONS --- */
369 |
370 | /*! @function
371 | @abstract Integer hash function
372 | @param key The integer [khint32_t]
373 | @return The hash value [khint_t]
374 | */
375 | #define kh_int_hash_func(key) (khint32_t)(key)
376 | /*! @function
377 | @abstract Integer comparison function
378 | */
379 | #define kh_int_hash_equal(a, b) ((a) == (b))
380 | /*! @function
381 | @abstract 64-bit integer hash function
382 | @param key The integer [khint64_t]
383 | @return The hash value [khint_t]
384 | */
385 | #define kh_int64_hash_func(key) (khint32_t)((key)>>33^(key)^(key)<<11)
386 | /*! @function
387 | @abstract 64-bit integer comparison function
388 | */
389 | #define kh_int64_hash_equal(a, b) ((a) == (b))
390 | /*! @function
391 | @abstract const char* hash function
392 | @param s Pointer to a null terminated string
393 | @return The hash value
394 | */
395 | static kh_inline khint_t __ac_X31_hash_string(const char *s)
396 | {
397 | khint_t h = (khint_t)*s;
398 | if (h) for (++s ; *s; ++s) h = (h << 5) - h + (khint_t)*s;
399 | return h;
400 | }
401 | /*! @function
402 | @abstract Another interface to const char* hash function
403 | @param key Pointer to a null terminated string [const char*]
404 | @return The hash value [khint_t]
405 | */
406 | #define kh_str_hash_func(key) __ac_X31_hash_string(key)
407 | /*! @function
408 | @abstract Const char* comparison function
409 | */
410 | #define kh_str_hash_equal(a, b) (strcmp(a, b) == 0)
411 |
412 | static kh_inline khint_t __ac_Wang_hash(khint_t key)
413 | {
414 | key += ~(key << 15);
415 | key ^= (key >> 10);
416 | key += (key << 3);
417 | key ^= (key >> 6);
418 | key += ~(key << 11);
419 | key ^= (key >> 16);
420 | return key;
421 | }
422 | #define kh_int_hash_func2(key) __ac_Wang_hash((khint_t)key)
423 |
424 | /* --- END OF HASH FUNCTIONS --- */
425 |
426 | /* Other convenient macros... */
427 |
428 | /*!
429 | @abstract Type of the hash table.
430 | @param name Name of the hash table [symbol]
431 | */
432 | #define khash_t(name) kh_##name##_t
433 |
434 | /*! @function
435 | @abstract Initiate a hash table.
436 | @param name Name of the hash table [symbol]
437 | @return Pointer to the hash table [khash_t(name)*]
438 | */
439 | #define kh_init(name) kh_init_##name()
440 |
441 | /*! @function
442 | @abstract Destroy a hash table.
443 | @param name Name of the hash table [symbol]
444 | @param h Pointer to the hash table [khash_t(name)*]
445 | */
446 | #define kh_destroy(name, h) kh_destroy_##name(h)
447 |
448 | /*! @function
449 | @abstract Reset a hash table without deallocating memory.
450 | @param name Name of the hash table [symbol]
451 | @param h Pointer to the hash table [khash_t(name)*]
452 | */
453 | #define kh_clear(name, h) kh_clear_##name(h)
454 |
455 | /*! @function
456 | @abstract Resize a hash table.
457 | @param name Name of the hash table [symbol]
458 | @param h Pointer to the hash table [khash_t(name)*]
459 | @param s New size [khint_t]
460 | */
461 | #define kh_resize(name, h, s) kh_resize_##name(h, s)
462 |
463 | /*! @function
464 | @abstract Insert a key to the hash table.
465 | @param name Name of the hash table [symbol]
466 | @param h Pointer to the hash table [khash_t(name)*]
467 | @param k Key [type of keys]
468 | @param r Extra return code: -1 if the operation failed;
469 | 0 if the key is present in the hash table;
470 | 1 if the bucket is empty (never used); 2 if the element in
471 | the bucket has been deleted [int*]
472 | @return Iterator to the inserted element [khint_t]
473 | */
474 | #define kh_put(name, h, k, r) kh_put_##name(h, k, r)
475 |
476 | /*! @function
477 | @abstract Retrieve a key from the hash table.
478 | @param name Name of the hash table [symbol]
479 | @param h Pointer to the hash table [khash_t(name)*]
480 | @param k Key [type of keys]
481 | @return Iterator to the found element, or kh_end(h) if the element is absent [khint_t]
482 | */
483 | #define kh_get(name, h, k) kh_get_##name(h, k)
484 |
485 | /*! @function
486 | @abstract Remove a key from the hash table.
487 | @param name Name of the hash table [symbol]
488 | @param h Pointer to the hash table [khash_t(name)*]
489 | @param k Iterator to the element to be deleted [khint_t]
490 | */
491 | #define kh_del(name, h, k) kh_del_##name(h, k)
492 |
493 | /*! @function
494 | @abstract Test whether a bucket contains data.
495 | @param h Pointer to the hash table [khash_t(name)*]
496 | @param x Iterator to the bucket [khint_t]
497 | @return 1 if containing data; 0 otherwise [int]
498 | */
499 | #define kh_exist(h, x) (!__ac_iseither((h)->flags, (x)))
500 |
501 | /*! @function
502 | @abstract Get key given an iterator
503 | @param h Pointer to the hash table [khash_t(name)*]
504 | @param x Iterator to the bucket [khint_t]
505 | @return Key [type of keys]
506 | */
507 | #define kh_key(h, x) ((h)->keys[x])
508 |
509 | /*! @function
510 | @abstract Get value given an iterator
511 | @param h Pointer to the hash table [khash_t(name)*]
512 | @param x Iterator to the bucket [khint_t]
513 | @return Value [type of values]
514 | @discussion For hash sets, calling this results in segfault.
515 | */
516 | #define kh_val(h, x) ((h)->vals[x])
517 |
518 | /*! @function
519 | @abstract Alias of kh_val()
520 | */
521 | #define kh_value(h, x) ((h)->vals[x])
522 |
523 | /*! @function
524 | @abstract Get the start iterator
525 | @param h Pointer to the hash table [khash_t(name)*]
526 | @return The start iterator [khint_t]
527 | */
528 | #define kh_begin(h) (khint_t)(0)
529 |
530 | /*! @function
531 | @abstract Get the end iterator
532 | @param h Pointer to the hash table [khash_t(name)*]
533 | @return The end iterator [khint_t]
534 | */
535 | #define kh_end(h) ((h)->n_buckets)
536 |
537 | /*! @function
538 | @abstract Get the number of elements in the hash table
539 | @param h Pointer to the hash table [khash_t(name)*]
540 | @return Number of elements in the hash table [khint_t]
541 | */
542 | #define kh_size(h) ((h)->size)
543 |
544 | /*! @function
545 | @abstract Get the number of buckets in the hash table
546 | @param h Pointer to the hash table [khash_t(name)*]
547 | @return Number of buckets in the hash table [khint_t]
548 | */
549 | #define kh_n_buckets(h) ((h)->n_buckets)
550 |
551 | /*! @function
552 | @abstract Iterate over the entries in the hash table
553 | @param h Pointer to the hash table [khash_t(name)*]
554 | @param kvar Variable to which key will be assigned
555 | @param vvar Variable to which value will be assigned
556 | @param code Block of code to execute
557 | */
558 | #define kh_foreach(h, kvar, vvar, code) { khint_t __i; \
559 | for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \
560 | if (!kh_exist(h,__i)) continue; \
561 | (kvar) = kh_key(h,__i); \
562 | (vvar) = kh_val(h,__i); \
563 | code; \
564 | } }
565 |
566 | /*! @function
567 | @abstract Iterate over the values in the hash table
568 | @param h Pointer to the hash table [khash_t(name)*]
569 | @param vvar Variable to which value will be assigned
570 | @param code Block of code to execute
571 | */
572 | #define kh_foreach_value(h, vvar, code) { khint_t __i; \
573 | for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \
574 | if (!kh_exist(h,__i)) continue; \
575 | (vvar) = kh_val(h,__i); \
576 | code; \
577 | } }
578 |
579 | /* More convenient interfaces */
580 |
581 | /*! @function
582 | @abstract Instantiate a hash set containing integer keys
583 | @param name Name of the hash table [symbol]
584 | */
585 | #define KHASH_SET_INIT_INT(name) \
586 | KHASH_INIT(name, khint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal)
587 |
588 | /*! @function
589 | @abstract Instantiate a hash map containing integer keys
590 | @param name Name of the hash table [symbol]
591 | @param khval_t Type of values [type]
592 | */
593 | #define KHASH_MAP_INIT_INT(name, khval_t) \
594 | KHASH_INIT(name, khint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal)
595 |
596 | /*! @function
597 | @abstract Instantiate a hash set containing 64-bit integer keys
598 | @param name Name of the hash table [symbol]
599 | */
600 | #define KHASH_SET_INIT_INT64(name) \
601 | KHASH_INIT(name, khint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal)
602 |
603 | /*! @function
604 | @abstract Instantiate a hash map containing 64-bit integer keys
605 | @param name Name of the hash table [symbol]
606 | @param khval_t Type of values [type]
607 | */
608 | #define KHASH_MAP_INIT_INT64(name, khval_t) \
609 | KHASH_INIT(name, khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal)
610 |
611 | typedef const char *kh_cstr_t;
612 | /*! @function
613 | @abstract Instantiate a hash map containing const char* keys
614 | @param name Name of the hash table [symbol]
615 | */
616 | #define KHASH_SET_INIT_STR(name) \
617 | KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal)
618 |
619 | /*! @function
620 | @abstract Instantiate a hash map containing const char* keys
621 | @param name Name of the hash table [symbol]
622 | @param khval_t Type of values [type]
623 | */
624 | #define KHASH_MAP_INIT_STR(name, khval_t) \
625 | KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal)
626 |
627 | #endif /* __AC_KHASH_H */
--------------------------------------------------------------------------------
/test/main.janet:
--------------------------------------------------------------------------------
1 | (import ../build/curl :as curl)
2 |
3 | (defn download
4 | "Download a file with curl easy"
5 | [url &opt to]
6 | (default to (last (string/split "/" url)))
7 | (def c (curl/easy/init))
8 | (with [file (file/open to :wb)]
9 | (var run-yet false)
10 | (defn progress [a b c d]
11 | "Progress function while downloading"
12 | (if (zero? b) (break))
13 | (def out-of-50
14 | (let [x (math/floor (/ (* b 50) a))]
15 | (if (= x x) x 0)))
16 | (def rest (- 50 out-of-50))
17 | (if run-yet
18 | (:write stdout "\e[F\e[F"))
19 | (set run-yet true)
20 | (print "Downloading \e[36m" url "\n\e[34m["
21 | (string/repeat "." out-of-50) (string/repeat " " rest) "]\e[0m"))
22 | (:setopt c
23 | :url url
24 | :write-function (fn [buf] (file/write file buf))
25 | :no-progress? false
26 | :progress-function progress)
27 | (:perform c)
28 | (print "Wrote to \e[36m" to "\e[0m")))
29 |
30 | (download "https://upload.wikimedia.org/wikipedia/commons/7/79/Big_Buck_Bunny_small.ogv"
31 | "test/DOWNLOAD")
32 |
--------------------------------------------------------------------------------