API.htm 42.8 KB
Newer Older
1
<!doctype html>
2 3
<html>
<head>
4 5 6 7 8 9 10 11
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-54391264-2"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-54391264-2');
12
</script>
13 14 15
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro" rel="stylesheet">
16
<link rel="shortcut icon" type="image/png" href="../../images/favicon.png">
17
<title>The Ghostscript Interpreter Application Programming Interface (API)</title>
18
    <!-- Supercedes the API in DLL.htm -->
19 20
<link href="style.css" rel="stylesheet" type="text/css">
<link href="gs-style.css" rel="stylesheet" type="text/css">
21 22 23
</head>

<body>
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45

    <div class="header">
    <div class="row">
    <div class="col-lt-6 logo"><a href="https://www.ghostscript.com/"><img src="images/ghostscript_logo.png" width="108" height="119" alt=""></a></div>
        <div class="col-6"><div class="row"><div class="artifexlogo"><a href="https://artifex.com" target="_blank"><img src="images/Artifex_logo.png" width="194" height="40" alt=""></a></div>
        <div class="col-12"><div class="button button1"><a href="https://artifex.com/contact-us/" title="Contact Us" target="_blank">Contact Us</a></div>
        <div class="button button2 hidden-xs"><a href="https://www.ghostscript.com/download.html" title="Download">Download</a></div></div></div>
    </div>
    </div>
    </div>

    <div class="banner">
    <div class="row">
        <div class="col-12">The Ghostscript Interpreter Application Programming Interface (API)</div>
    </div>
    </div>

    <div class="main">
    <div class="row">
    <div id="sidebar">
    <div class="sidebar-item"></div>
    <div class="col-2 leftnav">
46
<ul>
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
            <li><a href="https://www.ghostscript.com/">Home</a></li>
            <li><a href="https://www.ghostscript.com/license.html">Licensing</a></li>
            <li><a href="https://www.ghostscript.com/releases.html">Releases</a></li>
            <li><a href="https://www.ghostscript.com/release_history.html">Release History</a></li>
            <li><a href="https://www.ghostscript.com/documentation.html" title="Documentation">Documentation</a></li>
            <li><a href="https://www.ghostscript.com/download.html" title="Download">Download</a></li>
            <li><a href="https://www.ghostscript.com/performance.html" title="Performance">Performance</a></li>
            <li><a href="http://jbig2dec.com/" title="jbig2dec">jbig2dec</a></li>
            <li><a href="http://git.ghostscript.com/?p=ghostpdl.git;a=summary">Source</a></li>
            <li><a href="http://bugs.ghostscript.com/">Bugs</a></li>
            <li><a href="https://www.ghostscript.com/faq.html" title="FAQ">FAQ</a></li>
        </ul>
    </div>
    </div>
    <div class="col-10 page">

63
<!--START EDITING HERE-->
64 65 66 67

<h2>Table of contents</h2>

<ul>
68 69 70
<li><a href="#API">What is the Ghostscript Interpreter API?</a></li>
<li><a href="#Exported_functions ">Exported functions</a></li>

71
<ul>
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
<li><a href="#revision"><code>gsapi_revision</code></a></li>
<li><a href="#new_instance"><code>gsapi_new_instance</code></a></li>
<li><a href="#delete_instance"><code>gsapi_delete_instance</code></a></li>
<li><a href="#set_stdio"><code>gsapi_set_stdio</code></a></li>
<li><a href="#set_poll"><code>gsapi_set_poll</code></a></li>
<li><a href="#set_display_callback"><code>gsapi_set_display_callback</code></a></li>
<li><a href="#set_arg_encoding"><code>gsapi_set_arg_encoding</code></a></li>
<li><a href="#run"><code>gsapi_run_string_begin</code></a></li>
<li><a href="#run"><code>gsapi_run_string_continue</code></a></li>
<li><a href="#run"><code>gsapi_run_string_end</code></a></li>
<li><a href="#run"><code>gsapi_run_string_with_length</code></a></li>
<li><a href="#run"><code>gsapi_run_string</code></a></li>
<li><a href="#init"><code>gsapi_init_with_args</code></a></li>
<li><a href="#run"><code>gsapi_run_*</code></a></li>
<li><a href="#exit"><code>gsapi_exit</code></a></li>
87 88
<li><a href="#add_fs"><code>gsapi_add_fs</code></a></li>
<li><a href="#remove_fs"><code>gsapi_remove_fs</code></a></li>
89
<li><a href="#return_codes">Return codes</a></li>
90
</ul>
91 92 93
<li><a href="#Example_usage">Example usage</a></li>
<li><a href="#stdio">Standard input and output</a></li>
<li><a href="#display">Display device</a></li>
94 95 96 97 98 99
</ul>

<!-- [1.2 end table of contents] =========================================== -->

<!-- [1.3 begin hint] ====================================================== -->

100
<p>For other information, see the <a href="Readme.htm">Ghostscript overview</a>.</p>
101 102 103 104

<p>
<b>WARNING:</b> The API described in this document is subject to changes in
future releases, possibly ones that are not backward compatible with what
105
is described here.</p>
106 107 108 109 110 111 112 113 114 115 116 117 118

<!-- [1.3 end hint] ======================================================== -->

<hr>

<!-- [1.0 end visible header] ============================================== -->

<!-- [2.0 begin contents] ================================================== -->


<h2><a name="API"></a>What is the Ghostscript Interpreter API?</h2>

<p>
119
The Ghostscript interpreter can be built as a dynamic link library
120 121 122 123
(DLL) on Microsoft Windows, as a shared object on the
Linux, Unix and MacOS X platforms. With some changes, it could be built
as a static library. This document describes the Application Programming
Interface (API) for the Ghostscript interpreter library.
124
This should not be confused with the
125
<a href="Lib.htm">Ghostscript library</a> which provides a graphics
126
library but not the interpreter.</p>
127
<p>
128
This supercedes the old <a href="DLL.htm">DLL</a> interface.</p>
129
<p>
130 131
To provide the interface described in the
<a href="Use.htm">usage documentation</a>, a smaller independent
132
executable loads the DLL/shared object.
133
This executable must provide all the interaction with the windowing system,
134
including image windows and, if necessary, a text window.</p>
135 136 137

<p>
The Ghostscript interpreter library's name and characteristics differ
138
for each platform:</p>
139 140 141

<ul>
<li>The Win32 DLL <code>gsdll32.dll</code>
142
can be used by multiple programs simultaneously, but only once
143
within each process.</li>
144 145 146

<li>The OS/2 DLL <code>gsdll2.dll</code> has
MULTIPLE NONSHARED data segments and can be called by multiple programs
147
simultaneously.</li>
148 149

<li>The Linux shared object <code>libgs.so</code>
150
can be used by multiple programs simultaneously.</li>
151
        </ul>
152 153
<p>
The source for the executable is in <code>dw</code>*.* (Windows),
154
<code>dp</code>*.* (OS/2) and  <code>dx</code>*.* (Linux/Unix).
155
See these source files for examples of how to use the DLL.</p>
156 157

<p>
158
The source file <tt>dxmainc.c</tt> can also serve as an example of how to use the
159
shared library component on MacOS X, providing the same command-line tool it does
160
on any linux, bsd or similar operating system.</p>
161 162
<p>
At this stage, Ghostscript does not support multiple instances
163
of the interpreter within a single process.</p>
164 165 166 167 168 169

<hr>

<h2><a name="Exported_functions"></a>Exported functions</h2>

<p>
170
The functions exported by the DLL/shared object are described
171 172
in the header file <a href="../psi/iapi.h"><code>iapi.h</code></a>
and are summarised below.  Omitted from the summary are
173
the calling convention (e.g. __stdcall), details of return
174
values and error handling.</p>
175 176 177 178


<ul>
<li><code>
179
int
180
<a href="#revision">gsapi_revision</a>
181 182
(gsapi_revision_t *pr, int len);
</code></li>
183 184

<li><code>
185
int
186 187
<a href="#new_instance">gsapi_new_instance</a>
(void **pinstance, void *caller_handle);
188
</code></li>
189 190

<li><code>
191
void
192 193
<a href="#delete_instance">gsapi_delete_instance</a>
(void *instance);
194
</code></li>
195 196

<li><code>
197
int
198 199 200 201 202
<a href="#set_stdio">gsapi_set_stdio</a>
(void *instance,
    int(*stdin_fn)(void *caller_handle, char *buf, int len),
    int(*stdout_fn)(void *caller_handle, const char *str, int len),
    int(*stderr_fn)(void *caller_handle, const char *str, int len));
203
</code></li>
204 205

<li><code>
206
int
207 208
<a href="#set_poll">gsapi_set_poll</a>
(void *instance, int(*poll_fn)(void *caller_handle));
209
</code></li>
210 211

<li><code>
212
int
213 214
<a href="#set_display_callback">gsapi_set_display_callback</a>
(void *instance, display_callback *callback);
215
</code></li>
216

217
<li><code>
218
int
219 220
<a href="#set_arg_encoding">gsapi_set_arg_encoding</a>
(void *instance, int encoding);
221
</code></li>
222

223
<li><code>
224
int
225 226
<a href="#init">gsapi_init_with_args</a>
(void *instance, int argc, char **argv);
227
</code></li>
228 229

<li><code>
230
int
231 232
<a href="#run">gsapi_run_string_begin</a>
(void *instance, int user_errors, int *pexit_code);
233
</code></li>
234 235

<li><code>
236
int
237
<a href="#run">gsapi_run_string_continue</a>
238
(void *instance,
239
    const char *str, unsigned int length, int user_errors, int *pexit_code);
240
</code></li>
241 242

<li><code>
243
int
244 245
<a href="#run">gsapi_run_string_end</a>
(void *instance, int user_errors, int *pexit_code);
246
</code></li>
247 248

<li><code>
249
int
250
<a href="#run">gsapi_run_string_with_length</a>
251
(void *instance,
252
    const char *str, unsigned int length, int user_errors, int *pexit_code);
253
</code></li>
254 255

<li><code>
256
int
257
<a href="#run">gsapi_run_string</a>
258
(void *instance,
259
    const char *str, int user_errors, int *pexit_code);
260
</code></li>
261 262

<li><code>
263
int
264
<a href="#run">gsapi_run_file</a>
265
(void *instance,
266
    const char *file_name, int user_errors, int *pexit_code);
267
</code></li>
268 269

<li><code>
270
int
271 272
<a href="#exit">gsapi_exit</a>
(void *instance);
273
</code></li>
274 275 276

<li><code>
int
277 278 279 280 281 282 283 284 285 286
<a href="#add_fs">gsapi_add_fs</a>
(void *instance,
    gsapi_fs_t *fs, void *secret);
</code></li>

<li><code>
void
<a href="#remove_fs">gsapi_remove_fs</a>
(void *instance,
    gsapi_fs_t *fs, void *secret);
287
</code></li>
288 289 290 291 292 293 294 295

</ul>

<h3><a name="revision"></a><code>gsapi_revision()</code></h3>

<blockquote>
This function returns the revision numbers and strings of the Ghostscript
interpreter library; you should call it before any other interpreter
296
library functions to make sure that the correct version of the
297 298 299 300 301 302 303 304 305 306 307 308 309
Ghostscript interpreter has been loaded.

<blockquote>
<pre>
typedef struct gsapi_revision_s {
    const char *product;
    const char *copyright;
    long revision;
    long revisiondate;
} gsapi_revision_t;
gsapi_revision_t r;

if (gsapi_revision(&amp;r, sizeof(r)) == 0) {
310
    if (r.revision &lt; 650)
311 312 313 314 315 316 317 318 319 320 321 322 323 324
       printf("Need at least Ghostscript 6.50");
}
else {
    printf("revision structure size is incorrect");
}
</pre></blockquote>
</blockquote>


<h3><a name="new_instance"></a><code>gsapi_new_instance()</code></h3>
<blockquote>
Create a new instance of Ghostscript.
This instance is passed to most other gsapi functions.
The caller_handle will be provided to callback functions.
325 326 327 328 329 330 331 332

<b>Unless Ghostscript has been compiled with the </code>GS_THREADSAFE</code>
define, only one instance at a time is supported.</b>

<p>Historically, Ghostscript has only supported a single instance; any
attempt to create more than one at a time would result in gsapi_new_instance
returning an error. Experimental work has been done to lift this
restriction; if Ghostscript is compiled with the GS_THREADSAFE define
333
then multiple concurrent instances are permitted.</p>
334 335 336 337 338

<p>While the core Ghostscript devices are believed to be thread safe
now, certain devices are known not to be (particularly the contrib
devices). The makefiles currently make no attempt to exclude these
from builds. If you enable GS_THREADSAFE then you should check to ensure
339
that you do not rely on such devices (check for global variable use).</p>
340 341 342 343
<p>
The first parameter, is a pointer to an opaque pointer (&quot;<code>void **</code>&quot;).
The opaque pointer (&quot;<code>void *</code>&quot;) must be initialised to <code>NULL</code> before
the call to <code>gsapi_new_instance()</code>. See <a href="#Example_1">Example 1</a>.
344 345 346 347 348 349 350
</blockquote>


<h3><a name="delete_instance"></a><code>gsapi_delete_instance()</code></h3>
<blockquote>
Destroy an instance of Ghostscript.
Before you call this, Ghostscript must have finished.
351
If Ghostscript has been initialised, you must call
352
<code>gsapi_exit</code> before <code>gsapi_delete_instance</code>.
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367
</blockquote>


<h3><a name="set_stdio"></a><code>gsapi_set_stdio()</code></h3>
<blockquote>
Set the callback functions for stdio
The stdin callback function should return the number of
characters read, 0 for EOF, or -1 for error.
The stdout and stderr callback functions should return
the number of characters written.
</blockquote>


<h3><a name="set_poll"></a><code>gsapi_set_poll()</code></h3>
<blockquote>
368
Set the callback function for polling. This function will only be called if
369 370
the Ghostscript interpreter was compiled with <code>CHECK_INTERRUPTS</code>
as described in <code><a href="../base/gpcheck.h">gpcheck.h</a></code>.
371 372 373 374
<p>
The polling function should return zero if all is well, and return
negative if it wants ghostscript to abort. This is often
used for checking for a user cancel. This can also be used for
375
handling window events or cooperative multitasking.</p>
376 377 378 379
<p>
The polling function is called very frequently during interpretation and
rendering so it must be fast. If the function is slow, then using a counter
to return 0 immediately some number of times can be used to reduce the
380
performance impact.</p>
381 382 383 384 385
</blockquote>

<h3><a name="set_display_callback"></a><code>gsapi_set_display_callback()</code></h3>
<blockquote>
Set the callback structure for the <a href="#display">display</a>
386 387
device.  If the <a href="#display">display</a> device is used,
this must be called after
388 389 390 391 392 393
<code>gsapi_new_instance()</code>
and before <code>gsapi_init_with_args()</code>.
See <code><a href="../base/gdevdsp.h">gdevdsp.h</a></code>
for more details.
</blockquote>

394 395 396 397 398 399 400 401 402 403 404 405 406 407
<h3><a name="set_arg_encoding"></a><code>gsapi_set_arg_encoding()</code></h3>
<blockquote>
Set the encoding used for the interpretation of all subsequent args
supplied via the gsapi interface on this instance. By default we
expect args to be in encoding 0 (the 'local' encoding for this OS).
On Windows this means "the currently selected codepage". On Linux this
typically means utf8. This means that omitting to call this function
will leave Ghostscript running exactly as it always has. Please note
that use of the 'local' encoding is now deprecated and should be
avoided in new code.
This must be called after  <code>gsapi_new_instance()</code>
and before <code>gsapi_init_with_args()</code>.
</blockquote>

408 409 410
<h3><a name="init"></a><code>gsapi_init_with_args()</code></h3>
<blockquote>
Initialise the interpreter.
411
This calls <code>gs_main_init_with_args()</code> in
412 413 414
<code><a href="../psi/imainarg.c">imainarg.c</a></code>.
See below for <a href="#return_codes">return codes</a>.
The arguments are the same as the "C" main function:
415
argv[0] is ignored and the user supplied arguments
416 417 418 419 420
are argv[1] to argv[argc-1].
</blockquote>

<h3><a name="run"></a><code>gsapi_run_*()</code></h3>
<blockquote>
421
The <code>gsapi_run_*</code> functions are like
422
<code>gs_main_run_*</code> except that the error_object is omitted.
423
If these functions return &lt;= -100, either quit or a fatal
424 425
error has occured.  You must call <code>gsapi_exit()</code> next.
The only exception is <code>gsapi_run_string_continue()</code>
426
which will return <code>gs_error_NeedInput</code> if all is well.
427 428
See below for <a href="#return_codes">return codes</a>.
<p>
429 430 431 432 433 434 435
The address passed in <code>pexit_code</code> will be used to return the
exit code for the interpreter in case of a quit or fatal error. The
<code>user_errors</code>  argument is normally set to zero to indicate that
errors should be handled through the normal mechanisms within the
interpreted code. If set to a negative value, the functions will return
an error code directly to the caller, bypassing the interpreted
language. The interpreted language's error handler is bypassed, regardless of
436
<code>user_errors</code> parameter, for the <code>gs_error_interrupt</code>
437
generated when <a href="#set_poll">the polling callback</a> returns a negative
438
value. A positive <code>user_errors</code> is treated the same as zero.</p>
439
<p>
440
There is a 64 KB length limit on any buffer submitted to a
441
<code>gsapi_run_*</code> function for processing. If you have more
442 443
than 65535 bytes of input then you must split it into smaller
pieces and submit each in a separate
444
<code>gsapi_run_string_continue()</code> call.</p>
445 446 447 448 449 450 451 452 453
</blockquote>

<h3><a name="exit"></a><code>gsapi_exit()</code></h3>
<blockquote>
Exit the interpreter.
This must be called on shutdown if <code>gsapi_init_with_args()</code>
has been called, and just before <code>gsapi_delete_instance()</code>.
</blockquote>

454
<h3><a name="add_fs"></a><code>gsapi_add_fs()</code></h3>
455
<blockquote>
456 457 458 459 460 461 462 463 464 465
Adds a new 'Filing System' to the interpreter.
This enables callers to implement their own filing systems. The system
starts with just the conventional 'file' handlers installed, to allow
access to the local filing system. Whenever files are to be opened
from the interpreter, the file paths are offered around each registered
filing system in turn (from most recently registered to oldest), until
either an error is given, or the file is opened successfully.
<p>
Details of the <code>gsapi_fs_t</code> are given
<a href="#gsapi_fs_t">below</a>.
466 467
</blockquote>

468 469 470 471 472 473 474
<h3><a name="remove_fs"></a><code>gsapi_remove_fs()</code></h3>
<blockquote>
Remove a previously registered 'Filing System' from the interpreter.
Both the function pointers within the <code>gs_fs_t</code> and the
secret value must match exactly.
<p>
</blockquote>
475 476 477 478

<h3><a name="return_codes"></a>Return codes</h3>

<p>
479
The <code>gsapi_init_with_args</code>, <code>gsapi_run_*</code> and
480 481 482 483
<code>gsapi_exit</code> functions return an integer code.</p>

<table>
<tr>
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516
    <th colspan="3">Return Codes from gsapi_*()</th>
</tr>
<tr>
    <th>CODE</th>
    <th colspan="2">STATUS</th>
</tr>
<tr>
    <td>0</td>
    <td colspan="2">No errors</td>
</tr>
<tr>
    <td>gs_error_Quit</td>
    <td colspan="2">"<code>quit</code>" has been executed. This is not an error. <code>gsapi_exit()</code> must be called next.</td>
</tr>
<tr>
    <td>gs_error_interrupt</td>
    <td colspan="2"><a href="#set_poll">The polling callback function</a> returned a negative value, requesting Ghostscript to abort.</td>
</tr>
<tr>
    <td>gs_error_NeedInput</td>
    <td colspan="2">More input is needed by <code>gsapi_run_string_continue()</code>. This is not an error.</td>
</tr>
<tr>
    <td>gs_error_Info</td>
    <td colspan="2">"<code>gs -h</code>" has been executed. This is not an error. <code>gsapi_exit()</code> must be called next.</td>
</tr>
<tr>
    <td>&lt; 0</td>
    <td colspan="2">Error</td>
</tr>
<tr>
    <td>&lt;= gs_error_Fatal</td>
    <td colspan="2">Fatal error. <code>gsapi_exit()</code> must be called next.</td>
517
</tr>
518
</table>
519

520 521 522
<p>
The <code>gsapi_run_*()</code> functions do not flush stdio.
If you want to see output from Ghostscript you
523
must do this explicitly as shown in the example below.</p>
524 525 526 527

<p>
When executing a string with <code>gsapi_run_string_*()</code>,
<code>currentfile</code> is the input from the string.
528
Reading from <code>%stdin</code> uses the stdin callback.</p>
529

530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795
<h3><a name="gsapi_fs_t"></a>gsapi_fs_t</h3>
<p>Each 'filing system' within gs is a structure of function
pointers; each function pointer gives a handler from taking a
different named resource (a file, a pipe, a printer, a scratch
file etc) and attempts to open it.

<pre>
typedef struct
{
    int (*open_file)(const gs_memory_t *mem,
                           void        *secret,
                     const char        *fname,
                     const char        *mode,
                           gp_file    **file);
    int (*open_pipe)(const gs_memory_t *mem,
                           void        *secret,
                     const char        *fname,
                           char        *rfname, /* 4096 bytes */
                     const char        *mode,
                           gp_file    **file);
    int (*open_scratch)(const gs_memory_t *mem,
                              void        *secret,
                        const char        *prefix,
                              char        *rfname, /* 4096 bytes */
                        const char        *mode,
                              int          rm,
                              gp_file    **file);
    int (*open_printer)(const gs_memory_t *mem,
                              void        *secret,
                              char        *fname, /* 4096 bytes */
                              int          binary,
                              gp_file    **file);
    int (*open_handle)(const gs_memory_t *mem,
                             void        *secret,
                             char        *fname, /* 4096 bytes */
                       const char        *mode,
                             gp_file    **file);
} gsapi_fs_t;
</pre>
  
<p>If the filename (always given in utf-8 format) is recognised as
being one that the filing system handles (perhaps by the prefix used),
then it should open the file, fill in the <code>gp_file</code>
pointer and return 0.
<p>If the filename is not-recognised as being one that the filing
system handles, then returning 0 will cause the filename to be
offered to other registered filing systems.
<p>If an error is returned (perhaps gs_error_invalidfileaccess),
then no other filing system will be allowed to try to open the
file. This provides a mechanism whereby a caller to gsapi can
completely control access to all files accessed via <code>gp_fopen</code>
at runtime.
<p>Note, that while most file access within ghostscript will be
redirected via these functions, stdio will not; see the existing
mechanisms within Ghostscript for intercepting/replacing this.
<ul>
<li>The <code>open_file</code> function pointer will be called when
something (most often a call to <code>gp_fopen</code>) attempts to
open a file.
<li>The <code>open_pipe</code> function pointer will be called when
something (most often a call to <code>gp_popen</code>) attempts to
open a pipe. <code>rfname</code> points to a 4K buffer in which the
actual name of the opened pipe should be returned.
<li>The <code>open_scratch</code> function pointer will be called when
something (most often a call to <code>gp_open_scratch_file</code> or
<code>gp_open_scratch_file_rm</code>) attempts to open a temporary file.
<code>rfname</code> points to a 4K buffer in which the actual name of
the opened pipe should be returned. If <code>rm</code> is true, then
the file should be set to delete itself when all handles to it are closed.
<li>The <code>open_printer</code> function pointer will be called when
something (most often a call to <code>gp_open_printer</code>) attempts
to open a stream to a printer. If <code>binary</code> is true, then
the stream should be opened as binary; most streams will be binary by
default - this has historical meaning on OS/2.
<li>The <code>open_handle</code> function pointer will be called when
something (most often a call via the postscript <code>%handle%</code>
IO device) attempts to open a Windows handle. This entry point will
never be called on non-Windows builds.
</ul>
<p>Any of these which are left as NULL will never be called; a filing
system with all of the entries left as NULL is therefore pointless.
<p>The most complex part of the implementation of these functions
is the creation of a <code>gp_file</code> instance to return. There are
some helper functions for this, best explained by example.
<p>Let us consider a hypothetical filing system that encrypts data as
it is written, and decrypts it as it is read back. As each file is
read and written the encryption/decryption routines will need to use
some state, carried between calls to the filing system. We therefore
might define a new type 'derived' from <code>gp_file</code> as follows:

<pre>
typedef struct
{
   gp_file base;
   /* State private to the implementation of this file for encryption/decryption */
   /* For example: */
   int foo;
   char *bar;
} gp_file_crypt;
</pre>

<p>An implementation of <code>gs_fs_t</code> for our 'crypt' filing system
might then look like this:

<pre>
gsapi_fs_t gs_fs_crypt =
{
    crypt_open_file,
    NULL,            /* open_pipe */
    NULL,            /* open_scratch */
    NULL,            /* open_printer */
    NULL             /* open_handle */
};
</pre>

<p>In the above definition, we define a single handler, to cope with the
opening of our input/output files. If we wanted to encrypt/decrypt
other files too (perhaps the temporary files we produce) we'd need to
define additional handlers (such as <code>open_scratch</code>).

<p>Our handler might look as follows:
  
<pre>
int crypt_open_file(const gs_memory_t  *mem,
                          void         *secret,
                    const char         *filename,
                    const char         *mode,
                          gp_file     **file)
{
    gp_file_crypt crypt;

    /* Ignore any filename not starting with "crypt://" */
    if (strncmp(filename, "crypt://", 8) != 0)
        return 0;

    /* Allocate us an instance (and fill in the non-crypt-specific
     * internals) */
    crypt = (gp_file_crypt *)gp_file_alloc(mem, &crypt_ops, sizeof(*crypt), "gp_file_crypt");
    if (crypt == NULL)
        return gs_error_VMerror; /* Allocation failed */

    /* Setup the crypt-specific state */
    crypt->foo = 1;
    crypt->bar = gs_alloc_bytes(mem->non_gc_memory, 256, "bar");
    /* If allocations fail, we need to clean up before exiting */
    if (crypt->bar) {
        gp_file_dealloc(crypt);
	return gs_error_VMerror;
    }

    /* Return the new instance */
    *file = &crypt.base;
    return 0;
}
</pre>

<p>The crucial part of this function is the definition of <code>crypt_ops</code>,
an instance of the <code>gp_file_ops_t</code> type; a table of function pointers
that implement the actual operations required.

<pre>
typedef struct {
    int          (*close)(gp_file *);
    int          (*getc)(gp_file *);
    int          (*putc)(gp_file *, int);
    int          (*read)(gp_file *, size_t size, unsigned int count, void *buf);
    int          (*write)(gp_file *, size_t size, unsigned int count, const void *buf);
    int          (*seek)(gp_file *, gs_offset_t offset, int whence);
    gs_offset_t  (*tell)(gp_file *);
    int          (*eof)(gp_file *);
    gp_file     *(*dup)(gp_file *, const char *mode);
    int          (*seekable)(gp_file *);
    int          (*pread)(gp_file *, size_t count, gs_offset_t offset, void *buf);
    int          (*pwrite)(gp_file *, size_t count, gs_offset_t offset, const void *buf);
    int          (*is_char_buffered)(gp_file *file);
    void         (*fflush)(gp_file *file);
    int          (*ferror)(gp_file *file);
    FILE        *(*get_file)(gp_file *file);
    void         (*clearerr)(gp_file *file);
    gp_file     *(*reopen)(gp_file *f, const char *fname, const char *mode);
} gp_file_ops_t;
</pre>

<p>These functions generally follow the same patterns as the posix functions that match them,
and so in many cases we will describe these with references to such.
Whenever these routines are called, they will be passed a <code>gp_file</code> pointer.
This pointer will have originated from the <code>crypt_open_file</code> call, and so can
safely be cast back to a <code>gp_file_crypt</code> pointer to allow private data to be accessed.

<dl>
<dt><code>close(gp_file *)</code>
<dd>close the given file; free any storage in the crypt specific parts of <code>gp_file_crypt</code>,
but not the gp_file_crypt structure itself.

<dt><code>int getc(gp_file *)</code>
<dd>Get a single character from the file, returning it as an int (or -1 for EOF).
Behaves like <code>fgetc(FILE *)</code>.

<dt><code>int putc(gp_file *, int)</code>
<dd>Put a single character to the file, returning the character on success, or
EOF (and setting the error indicator) on error.
Behaves like <code>fgetc(FILE *)</code>.

<dt><code>int read(gp_file *, size_t size, unsigned int count, void *buf)</code>
<dd>Reads count entries of size bytes the file into buf, returning the number
of entries read. Behaves like <code>fread(FILE *, size, count, buf)</code>.

<dt><code>int write(gp_file *, size_t size, unsigned int count, const void *buf)</code>
<dd>Writes count entries of size bytes from buf into the file, returning the
number of entries written. Behaves like <code>fwrite(FILE *, size, count, buf)</code>.

<dt><code>int seek(gp_file *, gs_offset_t offset, int whence)</code>
<dd>Seeks within the file. Behaves like <code>fseek(FILE *, offset, whence)</code>.

<dt><code>gs_offset_t tell(gp_file *)</code>
<dd>Returns the current offset within the file. Behaves like <code>ftell(FILE *)</code>.

<dt><code>int eof(gp_file *)</code>
<dd>Returns 1 if we are at the end of the file, 0 otherwise. Behaves like
<code>feof(FILE *)</code>.

<dt><code>gp_file * dup(gp_file *, const char *mode)</code>
<dd>Optional function, only used if clist files are to be stored in this filing system.
Behaves like <code>fdup(FILE *)</code>. Leave NULL if not implemented.

<dt><code>int seekable(gp_file *)</code>
<dd>Returns 1 if the file is seekable, 0 otherwise. Certain output devices will
only work with seekable files.

<dt><code>int pread(gp_file *, size_t count, gs_offset_t offset, void *buf)</code>
<dd>Optional function, only used if clist files are to be stored in this filing system.
Behaves like an atomic <code>fseek(FILE *, offset, 0)</code> and <code>fread(FILE *, 1, count, buf)</code>.
Akin to <code>pread</code>.

<dt><code>int pwrite(gp_file *, size_t count, gs_offset_t offset, const void *buf)</code>
<dd>Optional function, only used if clist files are to be stored in this filing system.
Behaves like an atomic <code>fseek(FILE *, offset, 0)</code> and <code>fwrite(FILE *, 1, count, buf)</code>.
Akin to <code>pwrite</code>.

<dt><code>int is_char_buffered(gp_file *file)</code>
<dd>Returns 1 if the file is character buffered, 0 otherwise. Used for handling
reading from terminals. Very unlikely to be used, so returning 0 all the time
should be safe. Leave NULL to indicate "always 0".

<dt><code>void fflush(gp_file *file)</code>
<dd>Ensures that any buffered data is written to the file. Behaves like <code>fflush(FILE *)</code>.
Leave NULL to indicate that no flushing is ever required.

<dt><code>int ferror(gp_file *file)</code>
<dd>Returns non-zero if there has been an error, or 0 otherwise. Behaves like <code>ferror(FILE *)</code>.

<dt><code>FILE * get_file(gp_file *file)</code>
<dd>Optional: Gets the FILE * pointer that backs this file. Required for a few devices
that insist on working with FILE *'s direct. Generally safe to leave this set to NULL, and those
devices will fail gracefully.

<dt><code>void clearerr(gp_file *file)</code>
<dd>Clear the error and EOF values for a file. Behaves like <code>clearerror(FILE *)</code>.

<dt><code>gp_file * reopen(gp_file *f, const char *fname, const char *mode)</code>
<dd>Optional function, only used if the <code>gp_file</code> came from an <code>open_scratch</code>
call; can be left as NULL if the <code>open_scratch</code> pointer is set to NULL.
Reopen a stream with a different mode. Behaves like
<code>freopen(fname, mode, FILE *)</code>.
</dl>

796
<hr>
797
<h2><a name="Example_usage"></a>Example Usage</h2>
798
<p>To try out the following examples in a development environment like Microsoft's
799 800 801 802 803 804
developer tools or Metrowerks Codewarrior, create a new project, save the example
source code as a <tt>.c</tt> file and add it, along with the Ghostscript dll or shared
library. You will also need to make sure the Ghostscript headers are available, either
by adding their location (the <tt>src</tt> directory in the Ghostscript source
distribution) to the project's search path, or by copying ierrors.h and iapi.h into the
same directory as the example source.</p>
805

806
<h3><a name="Example_1"></a>Example 1</h3>
807 808 809
<pre>
/* Example of using GS DLL as a ps2pdf converter.  */

810
#if defined(_WIN32) &amp;&amp; !defined(_Windows)
811 812 813 814 815 816 817 818 819 820 821 822 823
# define _Windows
#endif
#ifdef _Windows
/* add this source to a project with gsdll32.dll, or compile it directly with:
 *   cl -D_Windows -Isrc -Febin\ps2pdf.exe ps2pdf.c bin\gsdll32.lib
 */
# include &lt;windows.h&gt;
# define GSDLLEXPORT __declspec(dllimport)
#endif

#include "ierrors.h"
#include "iapi.h"

824
void *minst = NULL;
825 826 827 828

int main(int argc, char *argv[])
{
    int code, code1;
829
    const char * gsargv[7];
830
    int gsargc;
831
    gsargv[0] = "";
832 833 834 835 836
    gsargv[1] = "-dNOPAUSE";
    gsargv[2] = "-dBATCH";
    gsargv[3] = "-dSAFER";
    gsargv[4] = "-sDEVICE=pdfwrite";
    gsargv[5] = "-sOutputFile=out.pdf";
837 838
    gsargv[6] = "input.ps";
    gsargc=7;
839 840 841

    code = gsapi_new_instance(&amp;minst, NULL);
    if (code &lt; 0)
842
    return 1;
843 844 845
    code = gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8);
    if (code == 0)
        code = gsapi_init_with_args(minst, gsargc, gsargv);
846
    code1 = gsapi_exit(minst);
847
    if ((code == 0) || (code == gs_error_Quit))
848
    code = code1;
849 850 851

    gsapi_delete_instance(minst);

852
    if ((code == 0) || (code == gs_error_Quit))
853
    return 0;
854 855 856 857 858 859 860 861
    return 1;
}
</pre>

<h3>Example 2</h3>
<pre>
/* Similar to command line gs */

862
#if defined(_WIN32) &amp;&amp; !defined(_Windows)
863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882
# define _Windows
#endif
#ifdef _Windows
/* Compile directly with:
 *   cl -D_Windows -Isrc -Febin\gstest.exe gstest.c bin\gsdll32.lib
 */
# include &lt;windows.h&gt;
# define GSDLLEXPORT __declspec(dllimport)
#endif
#include &lt;stdio.h&gt;
#include "ierrors.h"
#include "iapi.h"

/* stdio functions */
static int GSDLLCALL
gsdll_stdin(void *instance, char *buf, int len)
{
    int ch;
    int count = 0;
    while (count &lt; len) {
883 884 885 886 887 888 889
    ch = fgetc(stdin);
    if (ch == EOF)
        return 0;
    *buf++ = ch;
    count++;
    if (ch == '\n')
        break;
890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909
    }
    return count;
}

static int GSDLLCALL
gsdll_stdout(void *instance, const char *str, int len)
{
    fwrite(str, 1, len, stdout);
    fflush(stdout);
    return len;
}

static int GSDLLCALL
gsdll_stderr(void *instance, const char *str, int len)
{
    fwrite(str, 1, len, stderr);
    fflush(stderr);
    return len;
}

910
void *minst = NULL;
911 912 913 914 915 916 917 918
const char start_string[] = "systemdict /start get exec\n";

int main(int argc, char *argv[])
{
    int code, code1;
    int exit_code;

    code = gsapi_new_instance(&amp;minst, NULL);
919
    if (code &lt; 0)
920
    return 1;
921
    gsapi_set_stdio(minst, gsdll_stdin, gsdll_stdout, gsdll_stderr);
922 923 924
    code = gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8);
    if (code == 0)
        code = gsapi_init_with_args(minst, argc, argv);
925
    if (code == 0)
926
    code = gsapi_run_string(minst, start_string, 0, &amp;exit_code);
927
    code1 = gsapi_exit(minst);
928
    if ((code == 0) || (code == gs_error_Quit))
929
    code = code1;
930 931 932

    gsapi_delete_instance(minst);

933
    if ((code == 0) || (code == gs_error_Quit))
934
    return 0;
935 936 937 938 939 940
    return 1;
}
</pre>

<h3>Example 3</h3>

941 942
<p>Replace main() in either of the above with the following code,
showing how you can feed Ghostscript piecemeal:</p>
943 944 945 946 947 948 949 950 951
<pre>
const char *command = "1 2 add == flush\n";

int main(int argc, char *argv[])
{
    int code, code1;
    int exit_code;

    code = gsapi_new_instance(&amp;minst, NULL);
952
    if (code &lt; 0)
953
    return 1;
954 955 956
    code = gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8);
    if (code == 0)
        code = gsapi_init_with_args(minst, argc, argv);
957 958

    if (code == 0) {
959 960 961 962 963
    gsapi_run_string_begin(minst, 0, &amp;exit_code);
    gsapi_run_string_continue(minst, command, strlen(command), 0, &amp;exit_code);
    gsapi_run_string_continue(minst, "qu", 2, 0, &amp;exit_code);
    gsapi_run_string_continue(minst, "it", 2, 0, &amp;exit_code);
    gsapi_run_string_end(minst, 0, &amp;exit_code);
964 965 966
    }

    code1 = gsapi_exit(minst);
967
    if ((code == 0) || (code == gs_error_Quit))
968
    code = code1;
969 970 971

    gsapi_delete_instance(minst);

972
    if ((code == 0) || (code == gs_error_Quit))
973
    return 0;
974 975 976 977 978 979
    return 1;
}
</pre>

<h3>Example 4</h3>

980
<p>When feeding Ghostscript piecemeal buffers, one can use the normal
981
operators to configure things and invoke library routines. For example,
982
to parse a PDF file one could say:</p>
983 984 985 986 987

<pre>
    code = gsapi_run_string(minst, "(example.pdf) .runlibfile", 0, &amp;exit_code);
</pre>

988 989
<p>and Ghostscript would open and process the file named "example.pdf" as
if it had been passed as an argument to
990 991
<code>gsapi_init_with_args()</code>.</p>
<hr>
992
<h2><a name="Multiple_threads"></a>Multiple threads</h2>
993
<p>The Ghostscript library should have been compiled with a
994 995 996
thread safe run time library.
Synchronisation of threads is entirely up to the caller.
The exported <a href="#Exported_functions "><code>gsapi_*()</code></a>
997 998
functions must be called from one thread only.</p>
<hr>
999 1000
<h2><a name="stdio"></a>Standard input and output</h2>
<p>
1001
When using the Ghostscript interpreter library interface, you have a
1002
choice of two standard input/output methods.</p>
1003
<ul>
1004
<li>If you do nothing, the "C" stdio will be used.</li>
1005
<li>If you use <code>gsapi_set_stdio()</code>,  all stdio will
1006
 be redirected to the callback functions you provide.
1007 1008
 This would be used in a graphical user interface environment
 where stdio is not available, or where you wish to process
1009
 Ghostscript input or output.</li>
1010 1011
</ul>
<p>
1012
The callback functions are described in
1013
<a href="../psi/iapi.h"><code>iapi.h</code></a>.</p>
1014

1015
<hr>
1016 1017 1018
<h2><a name="display"></a>Display device</h2>
<p>
The <code>display</code> device is available for use with
1019
the Ghostscript interpreter library.  This is described in the file
1020 1021 1022
<code><a href="../base/gdevdsp.h">gdevdsp.h</a></code>.
This device provides you with access to the raster output of
Ghostscript.  It is your responsibility to copy this raster
1023
to a display window or printer.</p>
1024 1025 1026
<p>
To use this device, you must provide a callback structure
with addresses of a number of callback functions.
1027
The address of the callback structure is provided using
1028
<code>gsapi_set_display_callback()</code>.
1029
This must be called after
1030 1031
<code>gsapi_new_instance()</code>
and before
1032
<code>gsapi_init_with_args()</code>.</p>
1033 1034 1035
<p>
The callbacks are for device open, close, resize, sync, page,
memory allocation and updating.
1036
Each callback function contains a handle can be set using</p>
1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047
<blockquote>
  -sDisplayHandle=1234
</blockquote>
<p>
Where "1234" is a string. The API was changed to use a string
rather than an integer/long value when support for 64 bit systems
arrived. A display "handle" is often a pointer, and since these
command line options have to survive being processed by Postscript
machinery, and Postscript only permits 32 bit number values, a
different representation was required. Hence changing the value
to a string, so that 64 bit values can be supported. The string
1048
formats allowed are:</p>
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063
<blockquote>
<code>1234</code> - implicit base 10
</blockquote>
<blockquote>
<code>10#1234</code> - explicit base 10
</blockquote>
<blockquote>
<code>16#04d2</code> - explicit base 16
</blockquote>
<p>
The "number string" is parsed by the display device to retrieve
the number value, and is then assigned to the void pointer
parameter "pHandle" in the display device structure. Thus, for
a trivial example, passing <code>-sDisplayHandle=0</code> will result
in the first parameter passed to your display device callbacks being:
1064
<code>(void *)0</code>.</p>
1065
<p>
1066
The previous API, using a number value:</p>
1067 1068 1069
<blockquote>
  -dDisplayHandle=1234
</blockquote>
1070 1071 1072
<p>
is still supported on 32 bit systems, but will cause a "typecheck"
error on 64 bit systems, and is considered deprecated. It should
1073
not be used in new code.</p>
1074

1075
<p>
1076
The device raster format can be configured using</p>
1077 1078 1079
<blockquote>
  -dDisplayFormat=NNNN
</blockquote>
1080
<p>Options include</p>
1081
<ul>
1082 1083 1084 1085 1086 1087
<li> native, gray, RGB, CMYK or separation color spaces.</li>
<li> alpha byte (ignored).</li>
<li> 1 to 16 bits/component.</li>
<li> bigendian (RGB) or littleendian (BGR) order.</li>
<li> top first or bottom first raster.</li>
<li> 16 bits/pixel with 555 or 565 bitfields.</li>
1088
</ul>
1089
<p>The format values are described in
1090 1091
<code><a href="../base/gdevdsp.h">gdevdsp.h</a></code>.
The format is flexible enough to support common Windows, OS/2, Linux
1092
and Mac raster formats.  To select the display device with a
1093
Windows 24-bit RGB raster:</p>
1094 1095 1096 1097 1098 1099 1100 1101 1102 1103
<pre>
    char **nargv;
    char arg1[64];
    char arg2[64];
    char arg3[64];
    code = gsapi_new_instance(&amp;minst, NULL);
    gsapi_set_stdio(minst, gsdll_stdin, gsdll_stdout, gsdll_stderr);
    code = gsapi_set_display_callback(minst, &amp;display_callback);
    sprintf(arg1, "-sDEVICE=display");
    sprintf(arg2, "-dDisplayHandle=%d", 0);
1104 1105
    sprintf(arg3, "-dDisplayFormat=%d",
        DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120
        DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST);
    nargv = (char **)malloc((argc + 4) * sizeof(char *));
    nargv[0] = argv[0];
    nargv[1] = arg1;
    nargv[2] = arg2;
    nargv[3] = arg3;
    memcpy(nargv + 4, argv + 1, argc * sizeof(char *));
    argc += 3;
    code = gsapi_init_with_args(minst, argc, nargv);
</pre>

<p>
The display device provides you with the address and size of the
raster using the <code>display_size()</code> callback.
You are then responsible for displaying this raster.
1121
Some examples are in
1122
<code><a href="../psi/dwmain.c">dwmain.c</a></code> (Windows),
1123 1124
<code><a href="../psi/dpmain.c">dpmain.c</a></code> (OS/2) and
<code><a href="../psi/dxmain.c">dxmain.c</a></code> (X11/Linux), and
1125
<code><a href="../psi/dmmain.c">dmmain.c</a></code> (MacOS Classic or Carbon).</p>
1126
<p>
1127
On some platforms, the calling convention for the display device callbacks in
1128
<code><a href="../base/gdevdsp.h">gdevdsp.h</a></code>
1129
is not the same as the exported
1130
<a href="#Exported_functions "><code>gsapi_*()</code></a>
1131
functions in <a href="../psi/iapi.h"><code>iapi.h</code></a>.</p></p>
1132 1133 1134 1135 1136

<!-- [2.0 end contents] ==================================================== -->
<!-- [3.0 begin visible trailer] =========================================== -->
<hr>
<p>
1137
<small>Copyright &copy; 2000-2019 Artifex Software, Inc. All rights reserved.</small></p>
1138 1139 1140

<p>
This software is provided AS-IS with no warranty, either express or
1141
implied.</p>
1142 1143 1144 1145

This software is distributed under license and may not be copied, modified
or distributed except as expressly authorized under the terms of that
license.  Refer to licensing information at http://www.artifex.com/
1146 1147 1148 1149 1150 1151
or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.</p>

<p>
<small>Ghostscript version 9.23, 21 March 2018</p>

1152
<!-- [3.0 end visible trailer] ============================================= -->
1153 1154

<!--FINISH EDITING HERE-->
1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184

    </div>
    </div>
    </div>

    <div class="footer">
    <div class="row">
        <div class="col-7 footleft">
        <ul>
            <li><a href="https://artifex.com/contact-us/" target="blank">CONTACT US</a></li>
            <li><a href="https://artifex.com/about-us/" target="blank">ABOUT</a></li>
            <li><a href="https://ghostscript.com/security.html">SECURITY</a></li>
        </ul>
        </div>
        <div class="col-1 footcenter">
         <ul>
           <li><a href="https://artifex.com/support/" target="blank">SUPPORT</a></li>
           <li><a href="https://artifex.com/blog/artifex/" target="blank">BLOG</a></li>
           <li><a href="https://artifex.com/privacy-policy/" target="blank">PRIVACY</a></li>
           </ul>
        </div>
        <div class="col-ft-3 footright"><img src="images/Artifex_logo.png" width="194" height="40" alt=""/> <br>
              © Copyright 2019 Artifex Software, Inc. <br>
            All rights reserved.
        </div>
          </div>
    </div>

    <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script src="index.js"></script>
1185
</body>
1186
</html>