1 /* Various functions of utilitarian nature.
2 Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
4 This file is part of Wget.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
26 #else /* not HAVE_STRING_H */
28 #endif /* not HAVE_STRING_H */
30 #include <sys/types.h>
35 # include <sys/mman.h>
44 #ifdef HAVE_SYS_UTIME_H
45 # include <sys/utime.h>
49 # include <libc.h> /* for access() */
63 /* This section implements several wrappers around the basic
64 allocation routines. This is done for two reasons: first, so that
65 the callers of these functions need not consistently check for
66 errors. If there is not enough virtual memory for running Wget,
67 something is seriously wrong, and Wget exits with an appropriate
70 The second reason why these are useful is that, if DEBUG_MALLOC is
71 defined, they also provide a handy (if crude) malloc debugging
72 interface that checks memory leaks. */
74 /* Croak the fatal memory error and bail out with non-zero exit
77 memfatal (const char *what)
79 /* HACK: expose save_log_p from log.c, so we can turn it off in
80 order to prevent saving the log. Saving the log is dangerous
81 because logprintf() and logputs() can call malloc(), so this
82 could infloop. When logging is turned off, infloop can no longer
85 #### This is no longer really necessary because the new routines
86 in log.c cons only if the line exceeds eighty characters. But
87 this can come at the end of a line, so it's OK to be careful.
89 On a more serious note, it would be good to have a
90 log_forced_shutdown() routine that exposes this cleanly. */
91 extern int save_log_p;
94 logprintf (LOG_ALWAYS, _("%s: %s: Not enough memory.\n"), exec_name, what);
98 /* These functions end with _real because they need to be
99 distinguished from the debugging functions, and from the macros.
102 If memory debugging is not turned on, wget.h defines these:
104 #define xmalloc xmalloc_real
105 #define xfree xfree_real
106 #define xrealloc xrealloc_real
107 #define xstrdup xstrdup_real
109 In case of memory debugging, the definitions are a bit more
110 complex, because we want to provide more information, *and* we want
111 to call the debugging code. (The former is the reason why xmalloc
112 and friends need to be macros in the first place.) Then it looks
115 #define xmalloc(a) xmalloc_debug (a, __FILE__, __LINE__)
116 #define xfree(a) xfree_debug (a, __FILE__, __LINE__)
117 #define xrealloc(a, b) xrealloc_debug (a, b, __FILE__, __LINE__)
118 #define xstrdup(a) xstrdup_debug (a, __FILE__, __LINE__)
120 Each of the *_debug function does its magic and calls the real one. */
123 # define STATIC_IF_DEBUG static
125 # define STATIC_IF_DEBUG
128 STATIC_IF_DEBUG void *
129 xmalloc_real (size_t size)
131 void *ptr = malloc (size);
138 xfree_real (void *ptr)
143 STATIC_IF_DEBUG void *
144 xrealloc_real (void *ptr, size_t newsize)
148 /* Not all Un*xes have the feature of realloc() that calling it with
149 a NULL-pointer is the same as malloc(), but it is easy to
152 newptr = realloc (ptr, newsize);
154 newptr = malloc (newsize);
156 memfatal ("realloc");
160 STATIC_IF_DEBUG char *
161 xstrdup_real (const char *s)
167 copy = malloc (l + 1);
170 memcpy (copy, s, l + 1);
171 #else /* HAVE_STRDUP */
175 #endif /* HAVE_STRDUP */
182 /* Crude home-grown routines for debugging some malloc-related
185 * Counting the number of malloc and free invocations, and reporting
186 the "balance", i.e. how many times more malloc was called than it
187 was the case with free.
189 * Making malloc store its entry into a simple array and free remove
190 stuff from that array. At the end, print the pointers which have
191 not been freed, along with the source file and the line number.
192 This also has the side-effect of detecting freeing memory that
195 Note that this kind of memory leak checking strongly depends on
196 every malloc() being followed by a free(), even if the program is
197 about to finish. Wget is careful to free the data structure it
198 allocated in init.c. */
200 static int malloc_count, free_count;
206 } malloc_debug[100000];
208 /* Both register_ptr and unregister_ptr take O(n) operations to run,
209 which can be a real problem. It would be nice to use a hash table
210 for malloc_debug, but the functions in hash.c are not suitable
211 because they can call malloc() themselves. Maybe it would work if
212 the hash table were preallocated to a huge size, and if we set the
213 rehash threshold to 1.0. */
215 /* Register PTR in malloc_debug. Abort if this is not possible
216 (presumably due to the number of current allocations exceeding the
217 size of malloc_debug.) */
220 register_ptr (void *ptr, const char *file, int line)
223 for (i = 0; i < ARRAY_SIZE (malloc_debug); i++)
224 if (malloc_debug[i].ptr == NULL)
226 malloc_debug[i].ptr = ptr;
227 malloc_debug[i].file = file;
228 malloc_debug[i].line = line;
234 /* Unregister PTR from malloc_debug. Abort if PTR is not present in
235 malloc_debug. (This catches calling free() with a bogus pointer.) */
238 unregister_ptr (void *ptr)
241 for (i = 0; i < ARRAY_SIZE (malloc_debug); i++)
242 if (malloc_debug[i].ptr == ptr)
244 malloc_debug[i].ptr = NULL;
250 /* Print the malloc debug stats that can be gathered from the above
251 information. Currently this is the count of mallocs, frees, the
252 difference between the two, and the dump of the contents of
253 malloc_debug. The last part are the memory leaks. */
256 print_malloc_debug_stats (void)
259 printf ("\nMalloc: %d\nFree: %d\nBalance: %d\n\n",
260 malloc_count, free_count, malloc_count - free_count);
261 for (i = 0; i < ARRAY_SIZE (malloc_debug); i++)
262 if (malloc_debug[i].ptr != NULL)
263 printf ("0x%08ld: %s:%d\n", (long)malloc_debug[i].ptr,
264 malloc_debug[i].file, malloc_debug[i].line);
268 xmalloc_debug (size_t size, const char *source_file, int source_line)
270 void *ptr = xmalloc_real (size);
272 register_ptr (ptr, source_file, source_line);
277 xfree_debug (void *ptr, const char *source_file, int source_line)
279 assert (ptr != NULL);
281 unregister_ptr (ptr);
286 xrealloc_debug (void *ptr, size_t newsize, const char *source_file, int source_line)
288 void *newptr = xrealloc_real (ptr, newsize);
292 register_ptr (newptr, source_file, source_line);
294 else if (newptr != ptr)
296 unregister_ptr (ptr);
297 register_ptr (newptr, source_file, source_line);
303 xstrdup_debug (const char *s, const char *source_file, int source_line)
305 char *copy = xstrdup_real (s);
307 register_ptr (copy, source_file, source_line);
311 #endif /* DEBUG_MALLOC */
313 /* Copy the string formed by two pointers (one on the beginning, other
314 on the char after the last char) to a new, malloc-ed location.
317 strdupdelim (const char *beg, const char *end)
319 char *res = (char *)xmalloc (end - beg + 1);
320 memcpy (res, beg, end - beg);
321 res[end - beg] = '\0';
325 /* Parse a string containing comma-separated elements, and return a
326 vector of char pointers with the elements. Spaces following the
327 commas are ignored. */
329 sepstring (const char *s)
343 res = (char **)xrealloc (res, (i + 2) * sizeof (char *));
344 res[i] = strdupdelim (p, s);
347 /* Skip the blanks following the ','. */
355 res = (char **)xrealloc (res, (i + 2) * sizeof (char *));
356 res[i] = strdupdelim (p, s);
361 /* Return pointer to a static char[] buffer in which zero-terminated
362 string-representation of TM (in form hh:mm:ss) is printed. It is
363 shamelessly non-reentrant, but it doesn't matter, really.
365 If TM is non-NULL, the time_t of the current time will be stored
368 time_str (time_t *tm)
378 ptm = localtime (&tim);
379 sprintf (tms, "%02d:%02d:%02d", ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
383 /* Returns an error message for ERRNUM. #### This requires more work.
384 This function, as well as the whole error system, is very
387 uerrmsg (uerr_t errnum)
392 return _("Unknown/unsupported protocol");
395 return _("Invalid port specification");
398 return _("Invalid host name");
402 /* $@#@#$ compiler. */
407 /* The Windows versions of the following two functions are defined in
410 /* A cuserid() immitation using getpwuid(), to avoid hassling with
411 utmp. Besides, not all systems have cuesrid(). Under Windows, it
412 is defined in mswindows.c.
414 If WHERE is non-NULL, the username will be stored there.
415 Otherwise, it will be returned as a static buffer (as returned by
416 getpwuid()). In the latter case, the buffer should be copied
417 before calling getpwuid() or pwd_cuserid() again. */
420 pwd_cuserid (char *where)
424 if (!(pwd = getpwuid (getuid ())) || !pwd->pw_name)
428 strcpy (where, pwd->pw_name);
436 fork_to_background (void)
439 /* Whether we arrange our own version of opt.lfilename here. */
444 opt.lfilename = unique_name (DEFAULT_LOGFILE);
456 /* parent, no error */
457 printf (_("Continuing in background.\n"));
459 printf (_("Output will be written to `%s'.\n"), opt.lfilename);
462 /* child: keep running */
464 #endif /* not WINDOWS */
466 /* Canonicalize PATH, and return a new path. The new path differs from PATH
468 Multple `/'s are collapsed to a single `/'.
469 Leading `./'s and trailing `/.'s are removed.
470 Trailing `/'s are removed.
471 Non-leading `../'s and trailing `..'s are handled by removing
472 portions of the path.
474 E.g. "a/b/c/./../d/.." will yield "a/b". This function originates
478 Always use '/' as stub_char.
479 Don't check for local things using canon_stat.
480 Change the original string instead of strdup-ing.
481 React correctly when beginning with `./' and `../'. */
483 path_simplify (char *path)
485 register int i, start, ddot;
491 /*stub_char = (*path == '/') ? '/' : '.';*/
494 /* Addition: Remove all `./'-s preceding the string. If `../'-s
495 precede, put `/' in front and remove them too. */
500 if (path[i] == '.' && path[i + 1] == '/')
502 else if (path[i] == '.' && path[i + 1] == '.' && path[i + 2] == '/')
511 strcpy (path, path + i - ddot);
513 /* Replace single `.' or `..' with `/'. */
514 if ((path[0] == '.' && path[1] == '\0')
515 || (path[0] == '.' && path[1] == '.' && path[2] == '\0'))
521 /* Walk along PATH looking for things to compact. */
528 while (path[i] && path[i] != '/')
533 /* If we didn't find any slashes, then there is nothing left to do. */
537 /* Handle multiple `/'s in a row. */
538 while (path[i] == '/')
541 if ((start + 1) != i)
543 strcpy (path + start + 1, path + i);
547 /* Check for trailing `/'. */
548 if (start && !path[i])
555 /* Check for `../', `./' or trailing `.' by itself. */
558 /* Handle trailing `.' by itself. */
563 if (path[i + 1] == '/')
565 strcpy (path + i, path + i + 1);
566 i = (start < 0) ? 0 : start;
570 /* Handle `../' or trailing `..' by itself. */
571 if (path[i + 1] == '.' &&
572 (path[i + 2] == '/' || !path[i + 2]))
574 while (--start > -1 && path[start] != '/');
575 strcpy (path + start + 1, path + i + 2);
576 i = (start < 0) ? 0 : start;
589 /* "Touch" FILE, i.e. make its atime and mtime equal to the time
590 specified with TM. */
592 touch (const char *file, time_t tm)
594 #ifdef HAVE_STRUCT_UTIMBUF
595 struct utimbuf times;
596 times.actime = times.modtime = tm;
599 times[0] = times[1] = tm;
602 if (utime (file, ×) == -1)
603 logprintf (LOG_NOTQUIET, "utime(%s): %s\n", file, strerror (errno));
606 /* Checks if FILE is a symbolic link, and removes it if it is. Does
607 nothing under MS-Windows. */
609 remove_link (const char *file)
614 if (lstat (file, &st) == 0 && S_ISLNK (st.st_mode))
616 DEBUGP (("Unlinking %s (symlink).\n", file));
619 logprintf (LOG_VERBOSE, _("Failed to unlink symlink `%s': %s\n"),
620 file, strerror (errno));
625 /* Does FILENAME exist? This is quite a lousy implementation, since
626 it supplies no error codes -- only a yes-or-no answer. Thus it
627 will return that a file does not exist if, e.g., the directory is
628 unreadable. I don't mind it too much currently, though. The
629 proper way should, of course, be to have a third, error state,
630 other than true/false, but that would introduce uncalled-for
631 additional complexity to the callers. */
633 file_exists_p (const char *filename)
636 return access (filename, F_OK) >= 0;
639 return stat (filename, &buf) >= 0;
643 /* Returns 0 if PATH is a directory, 1 otherwise (any kind of file).
644 Returns 0 on error. */
646 file_non_directory_p (const char *path)
649 /* Use lstat() rather than stat() so that symbolic links pointing to
650 directories can be identified correctly. */
651 if (lstat (path, &buf) != 0)
653 return S_ISDIR (buf.st_mode) ? 0 : 1;
656 /* Return a unique filename, given a prefix and count */
658 unique_name_1 (const char *fileprefix, int count)
664 filename = (char *)xmalloc (strlen (fileprefix) + numdigit (count) + 2);
665 sprintf (filename, "%s.%d", fileprefix, count);
668 filename = xstrdup (fileprefix);
670 if (!file_exists_p (filename))
679 /* Return a unique file name, based on PREFIX. */
681 unique_name (const char *prefix)
687 file = unique_name_1 (prefix, count++);
691 /* Create DIRECTORY. If some of the pathname components of DIRECTORY
692 are missing, create them first. In case any mkdir() call fails,
693 return its error status. Returns 0 on successful completion.
695 The behaviour of this function should be identical to the behaviour
696 of `mkdir -p' on systems where mkdir supports the `-p' option. */
698 make_directory (const char *directory)
704 /* Make a copy of dir, to be able to write to it. Otherwise, the
705 function is unsafe if called with a read-only char *argument. */
706 STRDUP_ALLOCA (dir, directory);
708 /* If the first character of dir is '/', skip it (and thus enable
709 creation of absolute-pathname directories. */
710 for (i = (*dir == '/'); 1; ++i)
712 for (; dir[i] && dir[i] != '/'; i++)
717 /* Check whether the directory already exists. */
718 if (!file_exists_p (dir))
720 if (mkdir (dir, 0777) < 0)
731 static int in_acclist PARAMS ((const char *const *, const char *, int));
733 /* Determine whether a file is acceptable to be followed, according to
734 lists of patterns to accept/reject. */
736 acceptable (const char *s)
740 while (l && s[l] != '/')
747 return (in_acclist ((const char *const *)opt.accepts, s, 1)
748 && !in_acclist ((const char *const *)opt.rejects, s, 1));
750 return in_acclist ((const char *const *)opt.accepts, s, 1);
752 else if (opt.rejects)
753 return !in_acclist ((const char *const *)opt.rejects, s, 1);
757 /* Compare S1 and S2 frontally; S2 must begin with S1. E.g. if S1 is
758 `/something', frontcmp() will return 1 only if S2 begins with
759 `/something'. Otherwise, 0 is returned. */
761 frontcmp (const char *s1, const char *s2)
763 for (; *s1 && *s2 && (*s1 == *s2); ++s1, ++s2);
767 /* Iterate through STRLIST, and return the first element that matches
768 S, through wildcards or front comparison (as appropriate). */
770 proclist (char **strlist, const char *s, enum accd flags)
774 for (x = strlist; *x; x++)
775 if (has_wildcards_p (*x))
777 if (fnmatch (*x, s, FNM_PATHNAME) == 0)
782 char *p = *x + ((flags & ALLABS) && (**x == '/')); /* Remove '/' */
789 /* Returns whether DIRECTORY is acceptable for download, wrt the
790 include/exclude lists.
792 If FLAGS is ALLABS, the leading `/' is ignored in paths; relative
793 and absolute paths may be freely intermixed. */
795 accdir (const char *directory, enum accd flags)
797 /* Remove starting '/'. */
798 if (flags & ALLABS && *directory == '/')
802 if (!proclist (opt.includes, directory, flags))
807 if (proclist (opt.excludes, directory, flags))
813 /* Match the end of STRING against PATTERN. For instance:
815 match_backwards ("abc", "bc") -> 1
816 match_backwards ("abc", "ab") -> 0
817 match_backwards ("abc", "abc") -> 1 */
819 match_backwards (const char *string, const char *pattern)
823 for (i = strlen (string), j = strlen (pattern); i >= 0 && j >= 0; i--, j--)
824 if (string[i] != pattern[j])
826 /* If the pattern was exhausted, the match was succesful. */
833 /* Checks whether string S matches each element of ACCEPTS. A list
834 element are matched either with fnmatch() or match_backwards(),
835 according to whether the element contains wildcards or not.
837 If the BACKWARD is 0, don't do backward comparison -- just compare
840 in_acclist (const char *const *accepts, const char *s, int backward)
842 for (; *accepts; accepts++)
844 if (has_wildcards_p (*accepts))
846 /* fnmatch returns 0 if the pattern *does* match the
848 if (fnmatch (*accepts, s, 0) == 0)
855 if (match_backwards (s, *accepts))
860 if (!strcmp (s, *accepts))
868 /* Return the malloc-ed suffix of STR. For instance:
869 suffix ("foo.bar") -> "bar"
870 suffix ("foo.bar.baz") -> "baz"
871 suffix ("/foo/bar") -> NULL
872 suffix ("/foo.bar/baz") -> NULL */
874 suffix (const char *str)
878 for (i = strlen (str); i && str[i] != '/' && str[i] != '.'; i--);
880 return xstrdup (str + i);
885 /* Read a line from FP. The function reallocs the storage as needed
886 to accomodate for any length of the line. Reallocs are done
887 storage exponentially, doubling the storage after each overflow to
888 minimize the number of calls to realloc() and fgets(). The newline
889 character at the end of line is retained.
891 After end-of-file is encountered without anything being read, NULL
892 is returned. NULL is also returned on error. To distinguish
893 between these two cases, use the stdio function ferror(). */
896 read_whole_line (FILE *fp)
900 char *line = (char *)xmalloc (bufsize);
902 while (fgets (line + length, bufsize - length, fp))
904 length += strlen (line + length);
906 if (line[length - 1] == '\n')
908 /* fgets() guarantees to read the whole line, or to use up the
909 space we've given it. We can double the buffer
912 line = xrealloc (line, bufsize);
914 if (length == 0 || ferror (fp))
919 if (length + 1 < bufsize)
920 /* Relieve the memory from our exponential greediness. We say
921 `length + 1' because the terminating \0 is not included in
922 LENGTH. We don't need to zero-terminate the string ourselves,
923 though, because fgets() does that. */
924 line = xrealloc (line, length + 1);
928 /* Read FILE into memory. A pointer to `struct file_memory' are
929 returned; use struct element `content' to access file contents, and
930 the element `length' to know the file length. `content' is *not*
931 zero-terminated, and you should *not* read or write beyond the [0,
932 length) range of characters.
934 After you are done with the file contents, call read_file_free to
937 Depending on the operating system and the type of file that is
938 being read, read_file() either mmap's the file into memory, or
939 reads the file into the core using read().
941 If file is named "-", fileno(stdin) is used for reading instead.
942 If you want to read from a real file named "-", use "./-" instead. */
945 read_file (const char *file)
948 struct file_memory *fm;
950 int inhibit_close = 0;
952 /* Some magic in the finest tradition of Perl and its kin: if FILE
953 is "-", just use stdin. */
958 /* Note that we don't inhibit mmap() in this case. If stdin is
959 redirected from a regular file, mmap() will still work. */
962 fd = open (file, O_RDONLY);
965 fm = xmalloc (sizeof (struct file_memory));
970 if (fstat (fd, &buf) < 0)
972 fm->length = buf.st_size;
973 /* NOTE: As far as I know, the callers of this function never
974 modify the file text. Relying on this would enable us to
975 specify PROT_READ and MAP_SHARED for a marginal gain in
976 efficiency, but at some cost to generality. */
977 fm->content = mmap (NULL, fm->length, PROT_READ | PROT_WRITE,
979 if (fm->content == MAP_FAILED)
989 /* The most common reason why mmap() fails is that FD does not point
990 to a plain file. However, it's also possible that mmap() doesn't
991 work for a particular type of file. Therefore, whenever mmap()
992 fails, we just fall back to the regular method. */
993 #endif /* HAVE_MMAP */
996 size = 512; /* number of bytes fm->contents can
997 hold at any given time. */
998 fm->content = xmalloc (size);
1002 if (fm->length > size / 2)
1004 /* #### I'm not sure whether the whole exponential-growth
1005 thing makes sense with kernel read. On Linux at least,
1006 read() refuses to read more than 4K from a file at a
1007 single chunk anyway. But other Unixes might optimize it
1008 better, and it doesn't *hurt* anything, so I'm leaving
1011 /* Normally, we grow SIZE exponentially to make the number
1012 of calls to read() and realloc() logarithmic in relation
1013 to file size. However, read() can read an amount of data
1014 smaller than requested, and it would be unreasonably to
1015 double SIZE every time *something* was read. Therefore,
1016 we double SIZE only when the length exceeds half of the
1017 entire allocated size. */
1019 fm->content = xrealloc (fm->content, size);
1021 nread = read (fd, fm->content + fm->length, size - fm->length);
1023 /* Successful read. */
1024 fm->length += nread;
1034 if (size > fm->length && fm->length != 0)
1035 /* Due to exponential growth of fm->content, the allocated region
1036 might be much larger than what is actually needed. */
1037 fm->content = xrealloc (fm->content, fm->length);
1044 xfree (fm->content);
1049 /* Release the resources held by FM. Specifically, this calls
1050 munmap() or xfree() on fm->content, depending whether mmap or
1051 malloc/read were used to read in the file. It also frees the
1052 memory needed to hold the FM structure itself. */
1055 read_file_free (struct file_memory *fm)
1060 munmap (fm->content, fm->length);
1065 xfree (fm->content);
1070 /* Free the pointers in a NULL-terminated vector of pointers, then
1071 free the pointer itself. */
1073 free_vec (char **vec)
1084 /* Append vector V2 to vector V1. The function frees V2 and
1085 reallocates V1 (thus you may not use the contents of neither
1086 pointer after the call). If V1 is NULL, V2 is returned. */
1088 merge_vecs (char **v1, char **v2)
1098 /* To avoid j == 0 */
1103 for (i = 0; v1[i]; i++);
1105 for (j = 0; v2[j]; j++);
1106 /* Reallocate v1. */
1107 v1 = (char **)xrealloc (v1, (i + j + 1) * sizeof (char **));
1108 memcpy (v1 + i, v2, (j + 1) * sizeof (char *));
1113 /* A set of simple-minded routines to store strings in a linked list.
1114 This used to also be used for searching, but now we have hash
1117 /* It's a shame that these simple things like linked lists and hash
1118 tables (see hash.c) need to be implemented over and over again. It
1119 would be nice to be able to use the routines from glib -- see
1120 www.gtk.org for details. However, that would make Wget depend on
1121 glib, and I want to avoid dependencies to external libraries for
1122 reasons of convenience and portability (I suspect Wget is more
1123 portable than anything ever written for Gnome). */
1125 /* Append an element to the list. If the list has a huge number of
1126 elements, this can get slow because it has to find the list's
1127 ending. If you think you have to call slist_append in a loop,
1128 think about calling slist_prepend() followed by slist_nreverse(). */
1131 slist_append (slist *l, const char *s)
1133 slist *newel = (slist *)xmalloc (sizeof (slist));
1136 newel->string = xstrdup (s);
1141 /* Find the last element. */
1148 /* Prepend S to the list. Unlike slist_append(), this is O(1). */
1151 slist_prepend (slist *l, const char *s)
1153 slist *newel = (slist *)xmalloc (sizeof (slist));
1154 newel->string = xstrdup (s);
1159 /* Destructively reverse L. */
1162 slist_nreverse (slist *l)
1167 slist *next = l->next;
1175 /* Is there a specific entry in the list? */
1177 slist_contains (slist *l, const char *s)
1179 for (; l; l = l->next)
1180 if (!strcmp (l->string, s))
1185 /* Free the whole slist. */
1187 slist_free (slist *l)
1198 /* Sometimes it's useful to create "sets" of strings, i.e. special
1199 hash tables where you want to store strings as keys and merely
1200 query for their existence. Here is a set of utility routines that
1201 makes that transparent. */
1204 string_set_add (struct hash_table *ht, const char *s)
1206 /* First check whether the set element already exists. If it does,
1207 do nothing so that we don't have to free() the old element and
1208 then strdup() a new one. */
1209 if (hash_table_exists (ht, s))
1212 /* We use "1" as value. It provides us a useful and clear arbitrary
1213 value, and it consumes no memory -- the pointers to the same
1214 string "1" will be shared by all the key-value pairs in all `set'
1216 hash_table_put (ht, xstrdup (s), "1");
1219 /* Synonym for hash_table_exists... */
1222 string_set_exists (struct hash_table *ht, const char *s)
1224 return hash_table_exists (ht, s);
1228 string_set_free_mapper (void *key, void *value_ignored, void *arg_ignored)
1235 string_set_free (struct hash_table *ht)
1237 hash_table_map (ht, string_set_free_mapper, NULL);
1238 hash_table_destroy (ht);
1242 free_keys_and_values_mapper (void *key, void *value, void *arg_ignored)
1249 /* Another utility function: call free() on all keys and values of HT. */
1252 free_keys_and_values (struct hash_table *ht)
1254 hash_table_map (ht, free_keys_and_values_mapper, NULL);
1258 /* Engine for legible and legible_long_long; this function works on
1262 legible_1 (const char *repr)
1264 static char outbuf[128];
1269 /* Reset the pointers. */
1272 /* If the number is negative, shift the pointers. */
1278 /* How many digits before the first separator? */
1279 mod = strlen (inptr) % 3;
1281 for (i = 0; i < mod; i++)
1282 *outptr++ = inptr[i];
1283 /* Now insert the rest of them, putting separator before every
1285 for (i1 = i, i = 0; inptr[i1]; i++, i1++)
1287 if (i % 3 == 0 && i1 != 0)
1289 *outptr++ = inptr[i1];
1291 /* Zero-terminate the string. */
1296 /* Legible -- return a static pointer to the legibly printed long. */
1301 /* Print the number into the buffer. */
1302 long_to_string (inbuf, l);
1303 return legible_1 (inbuf);
1306 /* The same as legible(), but works on VERY_LONG_TYPE. See sysdep.h. */
1308 legible_very_long (VERY_LONG_TYPE l)
1311 /* Print the number into the buffer. */
1312 sprintf (inbuf, VERY_LONG_FORMAT, l);
1313 return legible_1 (inbuf);
1316 /* Count the digits in a (long) integer. */
1321 while ((a /= 10) != 0)
1326 /* Print NUMBER to BUFFER. This is equivalent to sprintf(buffer,
1327 "%ld", number), only much faster.
1329 BUFFER should accept 24 bytes. This should suffice for the longest
1330 numbers on 64-bit machines, including the `-' sign and the trailing
1333 long_to_string (char *buffer, long number)
1335 #if (SIZEOF_LONG != 4) && (SIZEOF_LONG != 8)
1337 sprintf (buffer, "%ld", number);
1338 #else /* (SIZEOF_LONG == 4) || (SIZEOF_LONG == 8) */
1348 #define FROB(figure) do { \
1349 if (force || number >= figure) \
1350 *p++ = number / figure + '0', number %= figure, force = 1; \
1352 #if SIZEOF_LONG == 8
1353 FROB (1000000000000000000L);
1354 FROB (100000000000000000L);
1355 FROB (10000000000000000L);
1356 FROB (1000000000000000L);
1357 FROB (100000000000000L);
1358 FROB (10000000000000L);
1359 FROB (1000000000000L);
1360 FROB (100000000000L);
1361 FROB (10000000000L);
1362 #endif /* SIZEOF_LONG == 8 */
1373 *p++ = number + '0';
1375 #endif /* (SIZEOF_LONG == 4) || (SIZEOF_LONG == 8) */
1378 /* This should probably be at a better place, but it doesn't really
1379 fit into html-parse.c. */
1381 /* The function returns the pointer to the malloc-ed quoted version of
1382 string s. It will recognize and quote numeric and special graphic
1383 entities, as per RFC1866:
1391 No other entities are recognized or replaced. */
1393 html_quote_string (const char *s)
1399 /* Pass through the string, and count the new size. */
1400 for (i = 0; *s; s++, i++)
1403 i += 4; /* `amp;' */
1404 else if (*s == '<' || *s == '>')
1405 i += 3; /* `lt;' and `gt;' */
1406 else if (*s == '\"')
1407 i += 5; /* `quot;' */
1411 res = (char *)xmalloc (i + 1);
1413 for (p = res; *s; s++)
1426 *p++ = (*s == '<' ? 'l' : 'g');