xref: /aosp_15_r20/external/libcups/cgi-bin/makedocset.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker  * Xcode documentation set generator.
3*5e7646d2SAndroid Build Coastguard Worker  *
4*5e7646d2SAndroid Build Coastguard Worker  * Copyright 2007-2012 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker  * Copyright 1997-2007 by Easy Software Products.
6*5e7646d2SAndroid Build Coastguard Worker  *
7*5e7646d2SAndroid Build Coastguard Worker  * Licensed under Apache License v2.0.  See the file "LICENSE" for more information.
8*5e7646d2SAndroid Build Coastguard Worker  *
9*5e7646d2SAndroid Build Coastguard Worker  * Usage:
10*5e7646d2SAndroid Build Coastguard Worker  *
11*5e7646d2SAndroid Build Coastguard Worker  *   makedocset directory *.tokens
12*5e7646d2SAndroid Build Coastguard Worker  */
13*5e7646d2SAndroid Build Coastguard Worker 
14*5e7646d2SAndroid Build Coastguard Worker /*
15*5e7646d2SAndroid Build Coastguard Worker  * Include necessary headers...
16*5e7646d2SAndroid Build Coastguard Worker  */
17*5e7646d2SAndroid Build Coastguard Worker 
18*5e7646d2SAndroid Build Coastguard Worker #include "cgi-private.h"
19*5e7646d2SAndroid Build Coastguard Worker #include <errno.h>
20*5e7646d2SAndroid Build Coastguard Worker 
21*5e7646d2SAndroid Build Coastguard Worker 
22*5e7646d2SAndroid Build Coastguard Worker /*
23*5e7646d2SAndroid Build Coastguard Worker  * Local structures...
24*5e7646d2SAndroid Build Coastguard Worker  */
25*5e7646d2SAndroid Build Coastguard Worker 
26*5e7646d2SAndroid Build Coastguard Worker typedef struct _cups_html_s		/**** Help file ****/
27*5e7646d2SAndroid Build Coastguard Worker {
28*5e7646d2SAndroid Build Coastguard Worker   char		*path;			/* Path to help file */
29*5e7646d2SAndroid Build Coastguard Worker   char		*title;			/* Title of help file */
30*5e7646d2SAndroid Build Coastguard Worker } _cups_html_t;
31*5e7646d2SAndroid Build Coastguard Worker 
32*5e7646d2SAndroid Build Coastguard Worker typedef struct _cups_section_s		/**** Help section ****/
33*5e7646d2SAndroid Build Coastguard Worker {
34*5e7646d2SAndroid Build Coastguard Worker   char		*name;			/* Section name */
35*5e7646d2SAndroid Build Coastguard Worker   cups_array_t	*files;			/* Files in this section */
36*5e7646d2SAndroid Build Coastguard Worker } _cups_section_t;
37*5e7646d2SAndroid Build Coastguard Worker 
38*5e7646d2SAndroid Build Coastguard Worker 
39*5e7646d2SAndroid Build Coastguard Worker /*
40*5e7646d2SAndroid Build Coastguard Worker  * Local functions...
41*5e7646d2SAndroid Build Coastguard Worker  */
42*5e7646d2SAndroid Build Coastguard Worker 
43*5e7646d2SAndroid Build Coastguard Worker static int	compare_html(_cups_html_t *a, _cups_html_t *b);
44*5e7646d2SAndroid Build Coastguard Worker static int	compare_sections(_cups_section_t *a, _cups_section_t *b);
45*5e7646d2SAndroid Build Coastguard Worker static int	compare_sections_files(_cups_section_t *a, _cups_section_t *b);
46*5e7646d2SAndroid Build Coastguard Worker static void	write_index(const char *path, help_index_t *hi);
47*5e7646d2SAndroid Build Coastguard Worker static void	write_info(const char *path, const char *revision);
48*5e7646d2SAndroid Build Coastguard Worker static void	write_nodes(const char *path, help_index_t *hi);
49*5e7646d2SAndroid Build Coastguard Worker 
50*5e7646d2SAndroid Build Coastguard Worker 
51*5e7646d2SAndroid Build Coastguard Worker /*
52*5e7646d2SAndroid Build Coastguard Worker  * 'main()' - Test the help index code.
53*5e7646d2SAndroid Build Coastguard Worker  */
54*5e7646d2SAndroid Build Coastguard Worker 
55*5e7646d2SAndroid Build Coastguard Worker int					/* O - Exit status */
main(int argc,char * argv[])56*5e7646d2SAndroid Build Coastguard Worker main(int  argc,				/* I - Number of command-line args */
57*5e7646d2SAndroid Build Coastguard Worker      char *argv[])			/* I - Command-line arguments */
58*5e7646d2SAndroid Build Coastguard Worker {
59*5e7646d2SAndroid Build Coastguard Worker   int		i;			/* Looping var */
60*5e7646d2SAndroid Build Coastguard Worker   char		path[1024],		/* Path to documentation */
61*5e7646d2SAndroid Build Coastguard Worker 		line[1024];		/* Line from file */
62*5e7646d2SAndroid Build Coastguard Worker   help_index_t	*hi;			/* Help index */
63*5e7646d2SAndroid Build Coastguard Worker   cups_file_t	*tokens,		/* Tokens.xml file */
64*5e7646d2SAndroid Build Coastguard Worker 		*fp;			/* Current file */
65*5e7646d2SAndroid Build Coastguard Worker 
66*5e7646d2SAndroid Build Coastguard Worker 
67*5e7646d2SAndroid Build Coastguard Worker   if (argc < 4)
68*5e7646d2SAndroid Build Coastguard Worker   {
69*5e7646d2SAndroid Build Coastguard Worker     puts("Usage: makedocset directory revision *.tokens");
70*5e7646d2SAndroid Build Coastguard Worker     return (1);
71*5e7646d2SAndroid Build Coastguard Worker   }
72*5e7646d2SAndroid Build Coastguard Worker 
73*5e7646d2SAndroid Build Coastguard Worker  /*
74*5e7646d2SAndroid Build Coastguard Worker   * Index the help documents...
75*5e7646d2SAndroid Build Coastguard Worker   */
76*5e7646d2SAndroid Build Coastguard Worker 
77*5e7646d2SAndroid Build Coastguard Worker   snprintf(path, sizeof(path), "%s/Contents/Resources/Documentation", argv[1]);
78*5e7646d2SAndroid Build Coastguard Worker   if ((hi = helpLoadIndex(NULL, path)) == NULL)
79*5e7646d2SAndroid Build Coastguard Worker   {
80*5e7646d2SAndroid Build Coastguard Worker     fputs("makedocset: Unable to index help files!\n", stderr);
81*5e7646d2SAndroid Build Coastguard Worker     return (1);
82*5e7646d2SAndroid Build Coastguard Worker   }
83*5e7646d2SAndroid Build Coastguard Worker 
84*5e7646d2SAndroid Build Coastguard Worker   snprintf(path, sizeof(path), "%s/Contents/Resources/Documentation/index.html",
85*5e7646d2SAndroid Build Coastguard Worker            argv[1]);
86*5e7646d2SAndroid Build Coastguard Worker   write_index(path, hi);
87*5e7646d2SAndroid Build Coastguard Worker 
88*5e7646d2SAndroid Build Coastguard Worker   snprintf(path, sizeof(path), "%s/Contents/Resources/Nodes.xml", argv[1]);
89*5e7646d2SAndroid Build Coastguard Worker   write_nodes(path, hi);
90*5e7646d2SAndroid Build Coastguard Worker 
91*5e7646d2SAndroid Build Coastguard Worker  /*
92*5e7646d2SAndroid Build Coastguard Worker   * Write the Info.plist file...
93*5e7646d2SAndroid Build Coastguard Worker   */
94*5e7646d2SAndroid Build Coastguard Worker 
95*5e7646d2SAndroid Build Coastguard Worker   snprintf(path, sizeof(path), "%s/Contents/Info.plist", argv[1]);
96*5e7646d2SAndroid Build Coastguard Worker   write_info(path, argv[2]);
97*5e7646d2SAndroid Build Coastguard Worker 
98*5e7646d2SAndroid Build Coastguard Worker  /*
99*5e7646d2SAndroid Build Coastguard Worker   * Merge the Tokens.xml files...
100*5e7646d2SAndroid Build Coastguard Worker   */
101*5e7646d2SAndroid Build Coastguard Worker 
102*5e7646d2SAndroid Build Coastguard Worker   snprintf(path, sizeof(path), "%s/Contents/Resources/Tokens.xml", argv[1]);
103*5e7646d2SAndroid Build Coastguard Worker   if ((tokens = cupsFileOpen(path, "w")) == NULL)
104*5e7646d2SAndroid Build Coastguard Worker   {
105*5e7646d2SAndroid Build Coastguard Worker     fprintf(stderr, "makedocset: Unable to create \"%s\": %s\n", path,
106*5e7646d2SAndroid Build Coastguard Worker 	    strerror(errno));
107*5e7646d2SAndroid Build Coastguard Worker     return (1);
108*5e7646d2SAndroid Build Coastguard Worker   }
109*5e7646d2SAndroid Build Coastguard Worker 
110*5e7646d2SAndroid Build Coastguard Worker   cupsFilePuts(tokens, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
111*5e7646d2SAndroid Build Coastguard Worker   cupsFilePuts(tokens, "<Tokens version=\"1.0\">\n");
112*5e7646d2SAndroid Build Coastguard Worker 
113*5e7646d2SAndroid Build Coastguard Worker   for (i = 3; i < argc; i ++)
114*5e7646d2SAndroid Build Coastguard Worker   {
115*5e7646d2SAndroid Build Coastguard Worker     if ((fp = cupsFileOpen(argv[i], "r")) == NULL)
116*5e7646d2SAndroid Build Coastguard Worker     {
117*5e7646d2SAndroid Build Coastguard Worker       fprintf(stderr, "makedocset: Unable to open \"%s\": %s\n", argv[i],
118*5e7646d2SAndroid Build Coastguard Worker 	      strerror(errno));
119*5e7646d2SAndroid Build Coastguard Worker       return (1);
120*5e7646d2SAndroid Build Coastguard Worker     }
121*5e7646d2SAndroid Build Coastguard Worker 
122*5e7646d2SAndroid Build Coastguard Worker     if (!cupsFileGets(fp, line, sizeof(line)) || strncmp(line, "<?xml ", 6) ||
123*5e7646d2SAndroid Build Coastguard Worker         !cupsFileGets(fp, line, sizeof(line)) || strncmp(line, "<Tokens ", 8))
124*5e7646d2SAndroid Build Coastguard Worker     {
125*5e7646d2SAndroid Build Coastguard Worker       fprintf(stderr, "makedocset: Bad Tokens.xml file \"%s\"!\n", argv[i]);
126*5e7646d2SAndroid Build Coastguard Worker       return (1);
127*5e7646d2SAndroid Build Coastguard Worker     }
128*5e7646d2SAndroid Build Coastguard Worker 
129*5e7646d2SAndroid Build Coastguard Worker     while (cupsFileGets(fp, line, sizeof(line)))
130*5e7646d2SAndroid Build Coastguard Worker     {
131*5e7646d2SAndroid Build Coastguard Worker       if (strcmp(line, "</Tokens>"))
132*5e7646d2SAndroid Build Coastguard Worker         cupsFilePrintf(tokens, "%s\n", line);
133*5e7646d2SAndroid Build Coastguard Worker     }
134*5e7646d2SAndroid Build Coastguard Worker 
135*5e7646d2SAndroid Build Coastguard Worker     cupsFileClose(fp);
136*5e7646d2SAndroid Build Coastguard Worker   }
137*5e7646d2SAndroid Build Coastguard Worker 
138*5e7646d2SAndroid Build Coastguard Worker   cupsFilePuts(tokens, "</Tokens>\n");
139*5e7646d2SAndroid Build Coastguard Worker 
140*5e7646d2SAndroid Build Coastguard Worker   cupsFileClose(tokens);
141*5e7646d2SAndroid Build Coastguard Worker 
142*5e7646d2SAndroid Build Coastguard Worker  /*
143*5e7646d2SAndroid Build Coastguard Worker   * Return with no errors...
144*5e7646d2SAndroid Build Coastguard Worker   */
145*5e7646d2SAndroid Build Coastguard Worker 
146*5e7646d2SAndroid Build Coastguard Worker   return (0);
147*5e7646d2SAndroid Build Coastguard Worker }
148*5e7646d2SAndroid Build Coastguard Worker 
149*5e7646d2SAndroid Build Coastguard Worker 
150*5e7646d2SAndroid Build Coastguard Worker /*
151*5e7646d2SAndroid Build Coastguard Worker  * 'compare_html()' - Compare the titles of two HTML files.
152*5e7646d2SAndroid Build Coastguard Worker  */
153*5e7646d2SAndroid Build Coastguard Worker 
154*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Result of comparison */
compare_html(_cups_html_t * a,_cups_html_t * b)155*5e7646d2SAndroid Build Coastguard Worker compare_html(_cups_html_t *a,		/* I - First file */
156*5e7646d2SAndroid Build Coastguard Worker              _cups_html_t *b)		/* I - Second file */
157*5e7646d2SAndroid Build Coastguard Worker {
158*5e7646d2SAndroid Build Coastguard Worker   return (_cups_strcasecmp(a->title, b->title));
159*5e7646d2SAndroid Build Coastguard Worker }
160*5e7646d2SAndroid Build Coastguard Worker 
161*5e7646d2SAndroid Build Coastguard Worker 
162*5e7646d2SAndroid Build Coastguard Worker /*
163*5e7646d2SAndroid Build Coastguard Worker  * 'compare_sections()' - Compare the names of two help sections.
164*5e7646d2SAndroid Build Coastguard Worker  */
165*5e7646d2SAndroid Build Coastguard Worker 
166*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Result of comparison */
compare_sections(_cups_section_t * a,_cups_section_t * b)167*5e7646d2SAndroid Build Coastguard Worker compare_sections(_cups_section_t *a,	/* I - First section */
168*5e7646d2SAndroid Build Coastguard Worker                  _cups_section_t *b)	/* I - Second section */
169*5e7646d2SAndroid Build Coastguard Worker {
170*5e7646d2SAndroid Build Coastguard Worker   return (_cups_strcasecmp(a->name, b->name));
171*5e7646d2SAndroid Build Coastguard Worker }
172*5e7646d2SAndroid Build Coastguard Worker 
173*5e7646d2SAndroid Build Coastguard Worker 
174*5e7646d2SAndroid Build Coastguard Worker /*
175*5e7646d2SAndroid Build Coastguard Worker  * 'compare_sections_files()' - Compare the number of files and section names.
176*5e7646d2SAndroid Build Coastguard Worker  */
177*5e7646d2SAndroid Build Coastguard Worker 
178*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Result of comparison */
compare_sections_files(_cups_section_t * a,_cups_section_t * b)179*5e7646d2SAndroid Build Coastguard Worker compare_sections_files(
180*5e7646d2SAndroid Build Coastguard Worker     _cups_section_t *a,			/* I - First section */
181*5e7646d2SAndroid Build Coastguard Worker     _cups_section_t *b)			/* I - Second section */
182*5e7646d2SAndroid Build Coastguard Worker {
183*5e7646d2SAndroid Build Coastguard Worker   int	ret = cupsArrayCount(b->files) - cupsArrayCount(a->files);
184*5e7646d2SAndroid Build Coastguard Worker 
185*5e7646d2SAndroid Build Coastguard Worker   if (ret)
186*5e7646d2SAndroid Build Coastguard Worker     return (ret);
187*5e7646d2SAndroid Build Coastguard Worker   else
188*5e7646d2SAndroid Build Coastguard Worker     return (_cups_strcasecmp(a->name, b->name));
189*5e7646d2SAndroid Build Coastguard Worker }
190*5e7646d2SAndroid Build Coastguard Worker 
191*5e7646d2SAndroid Build Coastguard Worker 
192*5e7646d2SAndroid Build Coastguard Worker /*
193*5e7646d2SAndroid Build Coastguard Worker  * 'write_index()' - Write an index file for the CUPS help.
194*5e7646d2SAndroid Build Coastguard Worker  */
195*5e7646d2SAndroid Build Coastguard Worker 
196*5e7646d2SAndroid Build Coastguard Worker static void
write_index(const char * path,help_index_t * hi)197*5e7646d2SAndroid Build Coastguard Worker write_index(const char   *path,		/* I - File to write */
198*5e7646d2SAndroid Build Coastguard Worker             help_index_t *hi)		/* I - Index of files */
199*5e7646d2SAndroid Build Coastguard Worker {
200*5e7646d2SAndroid Build Coastguard Worker   cups_file_t		*fp;		/* Output file */
201*5e7646d2SAndroid Build Coastguard Worker   help_node_t		*node;		/* Current help node */
202*5e7646d2SAndroid Build Coastguard Worker   _cups_section_t	*section,	/* Current section */
203*5e7646d2SAndroid Build Coastguard Worker 			key;		/* Section search key */
204*5e7646d2SAndroid Build Coastguard Worker   _cups_html_t		*html;		/* Current HTML file */
205*5e7646d2SAndroid Build Coastguard Worker   cups_array_t		*sections,	/* Sections in index */
206*5e7646d2SAndroid Build Coastguard Worker 			*sections_files,/* Sections sorted by size */
207*5e7646d2SAndroid Build Coastguard Worker 			*columns[3];	/* Columns in final HTML file */
208*5e7646d2SAndroid Build Coastguard Worker   int			column,		/* Current column */
209*5e7646d2SAndroid Build Coastguard Worker 			lines[3],	/* Number of lines in each column */
210*5e7646d2SAndroid Build Coastguard Worker 			min_column,	/* Smallest column */
211*5e7646d2SAndroid Build Coastguard Worker 			min_lines;	/* Smallest number of lines */
212*5e7646d2SAndroid Build Coastguard Worker 
213*5e7646d2SAndroid Build Coastguard Worker 
214*5e7646d2SAndroid Build Coastguard Worker  /*
215*5e7646d2SAndroid Build Coastguard Worker   * Build an array of sections and their files.
216*5e7646d2SAndroid Build Coastguard Worker   */
217*5e7646d2SAndroid Build Coastguard Worker 
218*5e7646d2SAndroid Build Coastguard Worker   sections = cupsArrayNew((cups_array_func_t)compare_sections, NULL);
219*5e7646d2SAndroid Build Coastguard Worker 
220*5e7646d2SAndroid Build Coastguard Worker   for (node = (help_node_t *)cupsArrayFirst(hi->nodes);
221*5e7646d2SAndroid Build Coastguard Worker        node;
222*5e7646d2SAndroid Build Coastguard Worker        node = (help_node_t *)cupsArrayNext(hi->nodes))
223*5e7646d2SAndroid Build Coastguard Worker   {
224*5e7646d2SAndroid Build Coastguard Worker     if (node->anchor)
225*5e7646d2SAndroid Build Coastguard Worker       continue;
226*5e7646d2SAndroid Build Coastguard Worker 
227*5e7646d2SAndroid Build Coastguard Worker     key.name = node->section ? node->section : "Miscellaneous";
228*5e7646d2SAndroid Build Coastguard Worker     if ((section = (_cups_section_t *)cupsArrayFind(sections, &key)) == NULL)
229*5e7646d2SAndroid Build Coastguard Worker     {
230*5e7646d2SAndroid Build Coastguard Worker       section        = (_cups_section_t *)calloc(1, sizeof(_cups_section_t));
231*5e7646d2SAndroid Build Coastguard Worker       section->name  = key.name;
232*5e7646d2SAndroid Build Coastguard Worker       section->files = cupsArrayNew((cups_array_func_t)compare_html, NULL);
233*5e7646d2SAndroid Build Coastguard Worker 
234*5e7646d2SAndroid Build Coastguard Worker       cupsArrayAdd(sections, section);
235*5e7646d2SAndroid Build Coastguard Worker     }
236*5e7646d2SAndroid Build Coastguard Worker 
237*5e7646d2SAndroid Build Coastguard Worker     html = (_cups_html_t *)calloc(1, sizeof(_cups_html_t));
238*5e7646d2SAndroid Build Coastguard Worker     html->path  = node->filename;
239*5e7646d2SAndroid Build Coastguard Worker     html->title = node->text;
240*5e7646d2SAndroid Build Coastguard Worker 
241*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(section->files, html);
242*5e7646d2SAndroid Build Coastguard Worker   }
243*5e7646d2SAndroid Build Coastguard Worker 
244*5e7646d2SAndroid Build Coastguard Worker  /*
245*5e7646d2SAndroid Build Coastguard Worker   * Build a sorted list of sections based on the number of files in each section
246*5e7646d2SAndroid Build Coastguard Worker   * and the section name...
247*5e7646d2SAndroid Build Coastguard Worker   */
248*5e7646d2SAndroid Build Coastguard Worker 
249*5e7646d2SAndroid Build Coastguard Worker   sections_files = cupsArrayNew((cups_array_func_t)compare_sections_files,
250*5e7646d2SAndroid Build Coastguard Worker                                 NULL);
251*5e7646d2SAndroid Build Coastguard Worker   for (section = (_cups_section_t *)cupsArrayFirst(sections);
252*5e7646d2SAndroid Build Coastguard Worker        section;
253*5e7646d2SAndroid Build Coastguard Worker        section = (_cups_section_t *)cupsArrayNext(sections))
254*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(sections_files, section);
255*5e7646d2SAndroid Build Coastguard Worker 
256*5e7646d2SAndroid Build Coastguard Worker  /*
257*5e7646d2SAndroid Build Coastguard Worker   * Then build three columns to hold everything, trying to balance the number of
258*5e7646d2SAndroid Build Coastguard Worker   * lines in each column...
259*5e7646d2SAndroid Build Coastguard Worker   */
260*5e7646d2SAndroid Build Coastguard Worker 
261*5e7646d2SAndroid Build Coastguard Worker   for (column = 0; column < 3; column ++)
262*5e7646d2SAndroid Build Coastguard Worker   {
263*5e7646d2SAndroid Build Coastguard Worker     columns[column] = cupsArrayNew((cups_array_func_t)compare_sections, NULL);
264*5e7646d2SAndroid Build Coastguard Worker     lines[column]   = 0;
265*5e7646d2SAndroid Build Coastguard Worker   }
266*5e7646d2SAndroid Build Coastguard Worker 
267*5e7646d2SAndroid Build Coastguard Worker   for (section = (_cups_section_t *)cupsArrayFirst(sections_files);
268*5e7646d2SAndroid Build Coastguard Worker        section;
269*5e7646d2SAndroid Build Coastguard Worker        section = (_cups_section_t *)cupsArrayNext(sections_files))
270*5e7646d2SAndroid Build Coastguard Worker   {
271*5e7646d2SAndroid Build Coastguard Worker     for (min_column = 0, min_lines = lines[0], column = 1;
272*5e7646d2SAndroid Build Coastguard Worker          column < 3;
273*5e7646d2SAndroid Build Coastguard Worker 	 column ++)
274*5e7646d2SAndroid Build Coastguard Worker     {
275*5e7646d2SAndroid Build Coastguard Worker       if (lines[column] < min_lines)
276*5e7646d2SAndroid Build Coastguard Worker       {
277*5e7646d2SAndroid Build Coastguard Worker         min_column = column;
278*5e7646d2SAndroid Build Coastguard Worker         min_lines  = lines[column];
279*5e7646d2SAndroid Build Coastguard Worker       }
280*5e7646d2SAndroid Build Coastguard Worker     }
281*5e7646d2SAndroid Build Coastguard Worker 
282*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(columns[min_column], section);
283*5e7646d2SAndroid Build Coastguard Worker     lines[min_column] += cupsArrayCount(section->files) + 2;
284*5e7646d2SAndroid Build Coastguard Worker   }
285*5e7646d2SAndroid Build Coastguard Worker 
286*5e7646d2SAndroid Build Coastguard Worker  /*
287*5e7646d2SAndroid Build Coastguard Worker   * Write the HTML file...
288*5e7646d2SAndroid Build Coastguard Worker   */
289*5e7646d2SAndroid Build Coastguard Worker 
290*5e7646d2SAndroid Build Coastguard Worker   if ((fp = cupsFileOpen(path, "w")) == NULL)
291*5e7646d2SAndroid Build Coastguard Worker   {
292*5e7646d2SAndroid Build Coastguard Worker     fprintf(stderr, "makedocset: Unable to create %s: %s\n", path,
293*5e7646d2SAndroid Build Coastguard Worker             strerror(errno));
294*5e7646d2SAndroid Build Coastguard Worker     exit(1);
295*5e7646d2SAndroid Build Coastguard Worker   }
296*5e7646d2SAndroid Build Coastguard Worker 
297*5e7646d2SAndroid Build Coastguard Worker   cupsFilePuts(fp, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 "
298*5e7646d2SAndroid Build Coastguard Worker                    "Transitional//EN\" "
299*5e7646d2SAndroid Build Coastguard Worker 		   "\"http://www.w3.org/TR/html4/loose.dtd\">\n"
300*5e7646d2SAndroid Build Coastguard Worker 		   "<html>\n"
301*5e7646d2SAndroid Build Coastguard Worker 		   "<head>\n"
302*5e7646d2SAndroid Build Coastguard Worker 		   "<title>CUPS Documentation</title>\n"
303*5e7646d2SAndroid Build Coastguard Worker 		   "<link rel='stylesheet' type='text/css' "
304*5e7646d2SAndroid Build Coastguard Worker 		   "href='cups-printable.css'>\n"
305*5e7646d2SAndroid Build Coastguard Worker 		   "</head>\n"
306*5e7646d2SAndroid Build Coastguard Worker 		   "<body>\n"
307*5e7646d2SAndroid Build Coastguard Worker 		   "<h1 class='title'>CUPS Documentation</h1>\n"
308*5e7646d2SAndroid Build Coastguard Worker 		   "<table width='100%' summary=''>\n"
309*5e7646d2SAndroid Build Coastguard Worker 		   "<tr>\n");
310*5e7646d2SAndroid Build Coastguard Worker 
311*5e7646d2SAndroid Build Coastguard Worker   for (column = 0; column < 3; column ++)
312*5e7646d2SAndroid Build Coastguard Worker   {
313*5e7646d2SAndroid Build Coastguard Worker     if (column)
314*5e7646d2SAndroid Build Coastguard Worker       cupsFilePuts(fp, "<td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>\n");
315*5e7646d2SAndroid Build Coastguard Worker 
316*5e7646d2SAndroid Build Coastguard Worker     cupsFilePuts(fp, "<td valign='top' width='33%'>");
317*5e7646d2SAndroid Build Coastguard Worker     for (section = (_cups_section_t *)cupsArrayFirst(columns[column]);
318*5e7646d2SAndroid Build Coastguard Worker          section;
319*5e7646d2SAndroid Build Coastguard Worker 	 section = (_cups_section_t *)cupsArrayNext(columns[column]))
320*5e7646d2SAndroid Build Coastguard Worker     {
321*5e7646d2SAndroid Build Coastguard Worker       cupsFilePrintf(fp, "<h2 class='title'>%s</h2>\n", section->name);
322*5e7646d2SAndroid Build Coastguard Worker       for (html = (_cups_html_t *)cupsArrayFirst(section->files);
323*5e7646d2SAndroid Build Coastguard Worker            html;
324*5e7646d2SAndroid Build Coastguard Worker 	   html = (_cups_html_t *)cupsArrayNext(section->files))
325*5e7646d2SAndroid Build Coastguard Worker 	cupsFilePrintf(fp, "<p class='compact'><a href='%s'>%s</a></p>\n",
326*5e7646d2SAndroid Build Coastguard Worker 	               html->path, html->title);
327*5e7646d2SAndroid Build Coastguard Worker     }
328*5e7646d2SAndroid Build Coastguard Worker     cupsFilePuts(fp, "</td>\n");
329*5e7646d2SAndroid Build Coastguard Worker   }
330*5e7646d2SAndroid Build Coastguard Worker   cupsFilePuts(fp, "</tr>\n"
331*5e7646d2SAndroid Build Coastguard Worker                    "</table>\n"
332*5e7646d2SAndroid Build Coastguard Worker 		   "</body>\n"
333*5e7646d2SAndroid Build Coastguard Worker 		   "</html>\n");
334*5e7646d2SAndroid Build Coastguard Worker   cupsFileClose(fp);
335*5e7646d2SAndroid Build Coastguard Worker }
336*5e7646d2SAndroid Build Coastguard Worker 
337*5e7646d2SAndroid Build Coastguard Worker 
338*5e7646d2SAndroid Build Coastguard Worker /*
339*5e7646d2SAndroid Build Coastguard Worker  * 'write_info()' - Write the Info.plist file.
340*5e7646d2SAndroid Build Coastguard Worker  */
341*5e7646d2SAndroid Build Coastguard Worker 
342*5e7646d2SAndroid Build Coastguard Worker static void
write_info(const char * path,const char * revision)343*5e7646d2SAndroid Build Coastguard Worker write_info(const char *path,		/* I - File to write */
344*5e7646d2SAndroid Build Coastguard Worker            const char *revision)	/* I - Subversion revision number */
345*5e7646d2SAndroid Build Coastguard Worker {
346*5e7646d2SAndroid Build Coastguard Worker   cups_file_t	*fp;			/* File */
347*5e7646d2SAndroid Build Coastguard Worker 
348*5e7646d2SAndroid Build Coastguard Worker 
349*5e7646d2SAndroid Build Coastguard Worker   if ((fp = cupsFileOpen(path, "w")) == NULL)
350*5e7646d2SAndroid Build Coastguard Worker   {
351*5e7646d2SAndroid Build Coastguard Worker     fprintf(stderr, "makedocset: Unable to create %s: %s\n", path,
352*5e7646d2SAndroid Build Coastguard Worker             strerror(errno));
353*5e7646d2SAndroid Build Coastguard Worker     exit(1);
354*5e7646d2SAndroid Build Coastguard Worker   }
355*5e7646d2SAndroid Build Coastguard Worker 
356*5e7646d2SAndroid Build Coastguard Worker   cupsFilePrintf(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
357*5e7646d2SAndroid Build Coastguard Worker 		     "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
358*5e7646d2SAndroid Build Coastguard Worker 		     "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
359*5e7646d2SAndroid Build Coastguard Worker 		     "<plist version=\"1.0\">\n"
360*5e7646d2SAndroid Build Coastguard Worker 		     "<dict>\n"
361*5e7646d2SAndroid Build Coastguard Worker 		     "\t<key>CFBundleIdentifier</key>\n"
362*5e7646d2SAndroid Build Coastguard Worker 		     "\t<string>org.cups.docset</string>\n"
363*5e7646d2SAndroid Build Coastguard Worker 		     "\t<key>CFBundleName</key>\n"
364*5e7646d2SAndroid Build Coastguard Worker 		     "\t<string>CUPS Documentation</string>\n"
365*5e7646d2SAndroid Build Coastguard Worker 		     "\t<key>CFBundleVersion</key>\n"
366*5e7646d2SAndroid Build Coastguard Worker 		     "\t<string>%d.%d.%s</string>\n"
367*5e7646d2SAndroid Build Coastguard Worker 		     "\t<key>CFBundleShortVersionString</key>\n"
368*5e7646d2SAndroid Build Coastguard Worker 		     "\t<string>%d.%d.%d</string>\n"
369*5e7646d2SAndroid Build Coastguard Worker 		     "\t<key>DocSetFeedName</key>\n"
370*5e7646d2SAndroid Build Coastguard Worker 		     "\t<string>cups.org</string>\n"
371*5e7646d2SAndroid Build Coastguard Worker 		     "\t<key>DocSetFeedURL</key>\n"
372*5e7646d2SAndroid Build Coastguard Worker 		     "\t<string>http://www.cups.org/org.cups.docset.atom"
373*5e7646d2SAndroid Build Coastguard Worker 		     "</string>\n"
374*5e7646d2SAndroid Build Coastguard Worker 		     "\t<key>DocSetPublisherIdentifier</key>\n"
375*5e7646d2SAndroid Build Coastguard Worker 		     "\t<string>org.cups</string>\n"
376*5e7646d2SAndroid Build Coastguard Worker 		     "\t<key>DocSetPublisherName</key>\n"
377*5e7646d2SAndroid Build Coastguard Worker 		     "\t<string>CUPS</string>\n"
378*5e7646d2SAndroid Build Coastguard Worker 		     "</dict>\n"
379*5e7646d2SAndroid Build Coastguard Worker 		     "</plist>\n",
380*5e7646d2SAndroid Build Coastguard Worker 		     CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR, revision,
381*5e7646d2SAndroid Build Coastguard Worker 		     CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR, CUPS_VERSION_PATCH);
382*5e7646d2SAndroid Build Coastguard Worker 
383*5e7646d2SAndroid Build Coastguard Worker   cupsFileClose(fp);
384*5e7646d2SAndroid Build Coastguard Worker }
385*5e7646d2SAndroid Build Coastguard Worker 
386*5e7646d2SAndroid Build Coastguard Worker 
387*5e7646d2SAndroid Build Coastguard Worker /*
388*5e7646d2SAndroid Build Coastguard Worker  * 'write_nodes()' - Write the Nodes.xml file.
389*5e7646d2SAndroid Build Coastguard Worker  */
390*5e7646d2SAndroid Build Coastguard Worker 
391*5e7646d2SAndroid Build Coastguard Worker static void
write_nodes(const char * path,help_index_t * hi)392*5e7646d2SAndroid Build Coastguard Worker write_nodes(const char   *path,		/* I - File to write */
393*5e7646d2SAndroid Build Coastguard Worker             help_index_t *hi)		/* I - Index of files */
394*5e7646d2SAndroid Build Coastguard Worker {
395*5e7646d2SAndroid Build Coastguard Worker   cups_file_t	*fp;			/* Output file */
396*5e7646d2SAndroid Build Coastguard Worker   int		id;			/* Current node ID */
397*5e7646d2SAndroid Build Coastguard Worker   help_node_t	*node;			/* Current help node */
398*5e7646d2SAndroid Build Coastguard Worker   int		subnodes;		/* Currently in Subnodes for file? */
399*5e7646d2SAndroid Build Coastguard Worker   int		needclose;		/* Need to close the current node? */
400*5e7646d2SAndroid Build Coastguard Worker 
401*5e7646d2SAndroid Build Coastguard Worker 
402*5e7646d2SAndroid Build Coastguard Worker   if ((fp = cupsFileOpen(path, "w")) == NULL)
403*5e7646d2SAndroid Build Coastguard Worker   {
404*5e7646d2SAndroid Build Coastguard Worker     fprintf(stderr, "makedocset: Unable to create %s: %s\n", path,
405*5e7646d2SAndroid Build Coastguard Worker             strerror(errno));
406*5e7646d2SAndroid Build Coastguard Worker     exit(1);
407*5e7646d2SAndroid Build Coastguard Worker   }
408*5e7646d2SAndroid Build Coastguard Worker 
409*5e7646d2SAndroid Build Coastguard Worker   cupsFilePuts(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
410*5e7646d2SAndroid Build Coastguard Worker 		   "<DocSetNodes version=\"1.0\">\n"
411*5e7646d2SAndroid Build Coastguard Worker 		   "<TOC>\n"
412*5e7646d2SAndroid Build Coastguard Worker 		   "<Node id=\"0\">\n"
413*5e7646d2SAndroid Build Coastguard Worker 		   "<Name>CUPS Documentation</Name>\n"
414*5e7646d2SAndroid Build Coastguard Worker 		   "<Path>Documentation/index.html</Path>\n"
415*5e7646d2SAndroid Build Coastguard Worker 		   "</Node>\n");
416*5e7646d2SAndroid Build Coastguard Worker 
417*5e7646d2SAndroid Build Coastguard Worker   for (node = (help_node_t *)cupsArrayFirst(hi->nodes), id = 1, subnodes = 0,
418*5e7646d2SAndroid Build Coastguard Worker            needclose = 0;
419*5e7646d2SAndroid Build Coastguard Worker        node;
420*5e7646d2SAndroid Build Coastguard Worker        node = (help_node_t *)cupsArrayNext(hi->nodes), id ++)
421*5e7646d2SAndroid Build Coastguard Worker   {
422*5e7646d2SAndroid Build Coastguard Worker     if (node->anchor)
423*5e7646d2SAndroid Build Coastguard Worker     {
424*5e7646d2SAndroid Build Coastguard Worker       if (!subnodes)
425*5e7646d2SAndroid Build Coastguard Worker       {
426*5e7646d2SAndroid Build Coastguard Worker         cupsFilePuts(fp, "<Subnodes>\n");
427*5e7646d2SAndroid Build Coastguard Worker 	subnodes = 1;
428*5e7646d2SAndroid Build Coastguard Worker       }
429*5e7646d2SAndroid Build Coastguard Worker 
430*5e7646d2SAndroid Build Coastguard Worker       cupsFilePrintf(fp, "<Node id=\"%d\">\n"
431*5e7646d2SAndroid Build Coastguard Worker                          "<Path>Documentation/%s</Path>\n"
432*5e7646d2SAndroid Build Coastguard Worker 			 "<Anchor>%s</Anchor>\n"
433*5e7646d2SAndroid Build Coastguard Worker 			 "<Name>%s</Name>\n"
434*5e7646d2SAndroid Build Coastguard Worker 			 "</Node>\n", id, node->filename, node->anchor,
435*5e7646d2SAndroid Build Coastguard Worker 		     node->text);
436*5e7646d2SAndroid Build Coastguard Worker     }
437*5e7646d2SAndroid Build Coastguard Worker     else
438*5e7646d2SAndroid Build Coastguard Worker     {
439*5e7646d2SAndroid Build Coastguard Worker       if (subnodes)
440*5e7646d2SAndroid Build Coastguard Worker       {
441*5e7646d2SAndroid Build Coastguard Worker         cupsFilePuts(fp, "</Subnodes>\n");
442*5e7646d2SAndroid Build Coastguard Worker 	subnodes = 0;
443*5e7646d2SAndroid Build Coastguard Worker       }
444*5e7646d2SAndroid Build Coastguard Worker 
445*5e7646d2SAndroid Build Coastguard Worker       if (needclose)
446*5e7646d2SAndroid Build Coastguard Worker         cupsFilePuts(fp, "</Node>\n");
447*5e7646d2SAndroid Build Coastguard Worker 
448*5e7646d2SAndroid Build Coastguard Worker       cupsFilePrintf(fp, "<Node id=\"%d\">\n"
449*5e7646d2SAndroid Build Coastguard Worker                          "<Path>Documentation/%s</Path>\n"
450*5e7646d2SAndroid Build Coastguard Worker 			 "<Name>%s</Name>\n", id, node->filename, node->text);
451*5e7646d2SAndroid Build Coastguard Worker       needclose = 1;
452*5e7646d2SAndroid Build Coastguard Worker     }
453*5e7646d2SAndroid Build Coastguard Worker   }
454*5e7646d2SAndroid Build Coastguard Worker 
455*5e7646d2SAndroid Build Coastguard Worker   if (subnodes)
456*5e7646d2SAndroid Build Coastguard Worker     cupsFilePuts(fp, "</Subnodes>\n");
457*5e7646d2SAndroid Build Coastguard Worker 
458*5e7646d2SAndroid Build Coastguard Worker   if (needclose)
459*5e7646d2SAndroid Build Coastguard Worker     cupsFilePuts(fp, "</Node>\n");
460*5e7646d2SAndroid Build Coastguard Worker 
461*5e7646d2SAndroid Build Coastguard Worker   cupsFilePuts(fp, "</TOC>\n"
462*5e7646d2SAndroid Build Coastguard Worker 		   "</DocSetNodes>\n");
463*5e7646d2SAndroid Build Coastguard Worker 
464*5e7646d2SAndroid Build Coastguard Worker   cupsFileClose(fp);
465*5e7646d2SAndroid Build Coastguard Worker }
466