libDtSearch: Coverity 86119
[oweals/cde.git] / cde / lib / DtSearch / dtsrutil.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /*
24  *   COMPONENT_NAME: austext
25  *
26  *   FUNCTIONS: clear_hitwords
27  *              clear_usrblk_record
28  *              get_hitlist_text
29  *              print_dittolist
30  *              print_usrblk_record
31  *
32  *   ORIGINS: 27
33  *
34  *
35  *   (C) COPYRIGHT International Business Machines Corp. 1991,1995
36  *   All Rights Reserved
37  *   Licensed Materials - Property of IBM
38  *   US Government Users Restricted Rights - Use, duplication or
39  *   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
40  */
41 /*********************** DTSRUTIL.C ***********************
42  * $XConsortium: dtsrutil.c /main/5 1996/08/12 13:18:30 cde-ibm $
43  * October 1991.
44  * Set of utility functions for opera User Interfaces (UIs),
45  * although may also be used by Opera Engine (OE) itself.
46  * Function free_dittolist() replaced by macro call to free_llist().
47  * Ausapi wrapped aa_free_dittolist around free_llist().
48  * DtSearch renamed aa_free_dittolist to DtSearchFreeResults().
49  *
50  * $Log$
51  * Revision 2.4  1996/03/13  22:54:21  miker
52  * Changed char to UCHAR several places.
53  *
54  * Revision 2.3  1996/03/05  16:05:45  miker
55  * Added print_stems().
56  *
57  * Revision 2.2  1995/10/25  18:36:09  miker
58  * Renamed from uiutil.c.  Added prolog.
59  *
60  * Log: uiutil.c,v
61  * Revision 2.1  1995/09/22  22:19:47  miker
62  * Freeze DtSearch 0.1, AusText 2.1.8
63  *
64  * Revision 1.13  1995/09/05  19:17:28  miker
65  * Minor name and function changes for DtSearch.  Made usrblk global.
66  */
67 #include "SearchE.h"
68 #include <string.h>
69 #include <stdlib.h>
70 #include <sys/stat.h>
71 #define MS_misc         1
72
73 /********#define DEBUG_CLEARREC*********/
74 /**********#define DEBUG_FAX***********/
75 #define PROGNAME        "DTSRUTIL"
76
77
78 /************************************************/
79 /*                                              */
80 /*                print_stems                   */
81 /*                                              */
82 /************************************************/
83 /* For debugging.  Prints passed stems array to aa_stderr. */
84 void    print_stems (int stemcount, void *stems, char *prefix)
85 {
86     int         i;
87     UCHAR       *cptr;
88
89     if (stemcount <= 0) {
90         fprintf (aa_stderr, "%s Stems array is empty.\n", prefix);
91         fflush (aa_stderr);
92         return;
93     }
94     fprintf (aa_stderr, "%s stemct = %d:\n", prefix, stemcount);
95     for (i=0;  i<stemcount;  i++) {
96         cptr = (UCHAR *) stems + (i * DtSrMAXWIDTH_HWORD);
97         if (i == 3 || i == 6)
98             fputc ('\n', aa_stderr);
99         fprintf (aa_stderr, "   #%d:'%c%s'",
100             i,  (*cptr < 32) ? '~' : *cptr,  cptr + 1);
101     }
102     fputc ('\n', aa_stderr);
103     fflush (aa_stderr);
104     return;
105 } /* print_stems() */
106
107
108 /************************************************/
109 /*                                              */
110 /*              print_dittolist                 */
111 /*                                              */
112 /************************************************/
113 /* Only for debugging in oe.  Dumps first 10 list nodes. */
114 void            print_dittolist (DtSrResult * dittolist, char *prefix)
115 {
116     DtSrResult     *dit;
117     char            datebuf[48];
118     int             maxcount = 10;
119
120     if (prefix == NULL)
121         prefix = "HITLIST";
122     if (dittolist == NULL) {
123         fprintf (aa_stderr, "%s Dittolist is empty.\n", prefix);
124         return;
125     }
126     fprintf (aa_stderr, "%s First %d hits on dittolist at %p:\n",
127         prefix, maxcount, (void *) dittolist);
128     for (dit = dittolist; dit != NULL && maxcount-- > 0; dit = dit->link) {
129         if (dit->objdate == 0)
130             strcpy (datebuf, "0");
131         else
132             strftime (datebuf, sizeof (datebuf), "%y/%m/%d",
133                 objdate2tm (dit->objdate));
134         fprintf (aa_stderr,
135             " dbn=%d dba=%d:%ld prox=%d sz=%ld date=%s key='%s'\n",
136             dit->dbn, dit->dba >> 24, (long)dit->dba & 0xffffffL,
137             dit->proximity, (long)dit->objsize,
138             datebuf, dit->reckey);
139         if (dit->abstractp)
140             if (dit->abstractp[0] != 0)
141                 fprintf (aa_stderr, "    abstract='%.50s'\n", dit->abstractp);
142     }
143     return;
144 }  /* print_dittolist() */
145
146 /************************************************/
147 /*                                              */
148 /*              get_hitlist_text                */
149 /*                                              */
150 /************************************************/
151 /* Converts dittolist into a single block of clean ascii text
152  * for use as a hitlist, or for printing out to hardcopy.
153  * Wraps lines intelligently to ensure no line is greater than maxlen.
154  * If maxlen == 0, no wrapping is performed.
155  * Returns static pointer to dynamically allocated buffer--
156  * if permanent copy is desired, caller must copy text
157  * to his own buffer before next call.
158  */
159 char           *get_hitlist_text (int maxlen)
160 {
161     static char    *text = NULL;
162     int             sofar;
163     char           *src, *targ, *eol;
164     DtSrResult     *dit;
165     char            sprintbuf[80];
166     size_t          mallocsz;
167
168     if (usrblk.dittocount <= 0L) {
169         sprintf (sprintbuf, catgets (dtsearch_catd, MS_misc, 96,
170                 "%s Hitlist is empty."), PROGNAME"96");
171         DtSearchAddMessage (sprintbuf);
172         return NULL;
173     }
174     if (maxlen > 0 && maxlen < DtSrMAX_DB_KEYSIZE + 7) {
175         sprintf (sprintbuf, PROGNAME "97 maxlen = %d is too small.", maxlen);
176         DtSearchAddMessage (sprintbuf);
177         return NULL;
178     }
179
180 /* Allocate enough memory for each item in ditto list */
181     mallocsz = usrblk.dittocount *
182         (usrblk.abstrbufsz + DtSrMAX_DB_KEYSIZE + 80L);
183     if (text != NULL)
184         free (text);
185     text = austext_malloc (mallocsz, PROGNAME "103", NULL);
186
187 /* Loop thru ditto list, creating text out of hitlist */
188     targ = text;
189     for (dit = usrblk.dittolist; dit != NULL; dit = dit->link) {
190         if (maxlen == 0) {
191             sprintf (targ, "%5d %-*s %s\n%n",
192                 dit->proximity,
193                 DtSrMAX_DB_KEYSIZE,
194                 dit->reckey,
195                 dit->abstractp,
196                 &sofar);
197             targ += sofar;
198         }
199         else    /* (maxlen > 0) */
200             /*
201              *  We may have more text than can fit on one line.
202              * Wrap lines to fit within maxlen. 
203              */
204         {
205             eol = targ + maxlen;
206             sprintf (targ, "%5d %-*s %n",
207                 dit->proximity,
208                 DtSrMAX_DB_KEYSIZE,
209                 dit->reckey,
210                 &sofar);
211             targ += sofar;
212             src = dit->abstractp;
213             for (;;) {
214                 while (targ < eol && *src != 0)
215                     *targ++ = *src++;
216                 *targ++ = '\n';
217                 if (*src == 0)
218                     break;
219                 eol = targ + maxlen;
220                 strcpy (targ, "         ");
221                 targ += 9;
222             }
223         }       /* end else (maxlen > 0) */
224     }   /* end loop on dittolist */
225
226     *targ = 0;  /* ...I don't know about you, but I always forget
227                  * this */
228
229     if (usrblk.debug & USRDBG_UTIL)
230         fprintf (aa_stderr, PROGNAME "160 "
231             "get_hitlist_text(): mallocsz=%lu textlen=%lu\n",
232             (unsigned long) mallocsz, (unsigned long) strlen (text));
233     return text;
234 }  /* get_hitlist_text() */
235
236
237 /****************************************/
238 /*                                      */
239 /*         print_usrblk_record          */
240 /*                                      */
241 /****************************************/
242 /* dumps out usrblk 'record' fields for debugging */
243 void    print_usrblk_record (char *prefix)
244 {
245     fprintf (aa_stderr, "%s usrblk_record(): dba=%ld:%ld objkey='%s'\n"
246         "  notesp=%p clearlen=%d cleartxt='%.30s'\n"
247         "  #hitw=%d hitw=%p abstr='%.24s'\n",
248         prefix,
249         (long)usrblk.dba >> 24, (long)usrblk.dba & 0xffffffL,
250         usrblk.objrec.or_objkey,
251         (void *) usrblk.notes,
252         (int)usrblk.clearlen,
253         NULLORSTR (usrblk.cleartext),
254         (int)usrblk.hitwcount,
255         (void *) usrblk.hitwords,
256         NULLORSTR (usrblk.abstrbuf));
257     return;
258 }  /* print_usrblk_record() */
259
260
261 /****************************************/
262 /*                                      */
263 /*         clear_usrblk_record          */
264 /*                                      */
265 /****************************************/
266 /* Clears and initializes all USRBLK fields that
267  * represent an opera record from vista, specifically
268  * objrec, notes, textblobs, clearlen, and cleartext.
269  * This function MUST NOT ALTER dba, hitwords, and hitwcount,
270  * because many callers require these things to remain untouched.
271  * If usrblk.objrec.or_objkey[0] == '\0',
272  * UI must presume that all record fields are invalid
273  * including usrblk.objfzkey and usrblk.abstract.
274  */
275 void            clear_usrblk_record (void)
276 {
277     usrblk.clearlen = 0;
278     if (usrblk.cleartext != NULL) {
279         free (usrblk.cleartext);
280         usrblk.cleartext = NULL;
281     }
282     free_llist (&usrblk.notes);
283     usrblk.objrec.or_objkey[0] = '\0';
284     if (usrblk.abstrbufsz > 0)
285         usrblk.abstrbuf[0] = 0;
286     if (usrblk.debug & USRDBG_RETRVL)
287         print_usrblk_record (PROGNAME "600 clear: ");
288     return;
289 }  /* clear_usrblk_record() */
290
291
292 /************************************************/
293 /*                                              */
294 /*               clear_hitwords                 */
295 /*                                              */
296 /************************************************/
297 /* clears hitwcount and array in usrblk */
298 void            clear_hitwords (void)
299 {
300     usrblk.hitwcount = 0;
301     if (usrblk.hitwords != NULL) {
302         free (usrblk.hitwords);
303         usrblk.hitwords = NULL;
304     }
305     return;
306 }  /* clear_hitwords() */
307
308
309 /*********************** DTSRUTIL.C ***********************/