diff options
Diffstat (limited to 'Master/texmf-dist/doc/latex/songs/songidx/titleidx.c')
-rw-r--r-- | Master/texmf-dist/doc/latex/songs/songidx/titleidx.c | 379 |
1 files changed, 0 insertions, 379 deletions
diff --git a/Master/texmf-dist/doc/latex/songs/songidx/titleidx.c b/Master/texmf-dist/doc/latex/songs/songidx/titleidx.c deleted file mode 100644 index cde08511a0c..00000000000 --- a/Master/texmf-dist/doc/latex/songs/songidx/titleidx.c +++ /dev/null @@ -1,379 +0,0 @@ -/* Copyright (C) 2012 Kevin W. Hamlen - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - * - * The latest version of this program can be obtained from - * http://songs.sourceforge.net. - */ - - -/* Create a LaTeX title index file from a title .sxd file. */ - -#if HAVE_CONFIG_H -# include "config.h" -#else -# include "vsconfig.h" -#endif - -#include "chars.h" -#include "songidx.h" -#include "fileio.h" - -#if HAVE_STRING_H -# include <string.h> -#elif HAVE_STRINGS_H -# include <strings.h> -#endif - -/* By convention, some word prefixes always get moved to the end of a title - * before it is indexed. For example, in English "The Song Title" becomes - * "Song Title, The". The following structure stores the list of these prefix - * words. The default is "The" and "A". */ -typedef struct prefix -{ - struct prefix *next; - WCHAR *s; -} -PREFIX; - -PREFIX pre_A = { NULL, ws_lit("A") }; -PREFIX pre_defaults = { &pre_A, ws_lit("The") }; - -/* freeprefixes(<list>) - * Free prefix list <list>. */ -static void -freeprefixes(pl) - PREFIX *pl; -{ - if (pl == &pre_defaults) return; - while (pl) - { - PREFIX *nxt = pl->next; - free(pl->s); - free(pl); - pl = nxt; - } -} - -/* rotate(<title>, <prelist>) - * If the first word of <title> is any word in list <prelist>, then <title> - * is modified in-place so that the word is shifted to the end of the string - * and preceded by a comma and a space. So for example, rotate("The Title", - * <prelist>) where <prelist> is the default results in "Title, The". Words - * in <prelist> are matched case-insensitively. If <title> begins with the - * marker character '*', that character is ignored and left unchanged. Note - * that <title> MUST be allocated with ONE EXTRA WCHAR OF STORAGE in order - * to leave room for the extra comma. - * Return Value: 1 if <title> was modified and 0 otherwise. */ -static int -rotate(s,pl) - WCHAR *s; - PREFIX *pl; -{ - const WCHAR *s2, *w2; - - w2 = NULL; - if (*s==wc_asterisk) ++s; - for (; pl; pl=pl->next) - { - for (s2=s, w2=pl->s; *w2; ++s2, ++w2) - if (wc_tolower(*s2)!=wc_tolower(*w2)) break; - if ((*w2 == wc_null) && (*s2 != wc_null) && !wc_isalpha(*s2)) break; - } - if (pl) - { - WCHAR buf[MAXLINELEN]; - size_t slen = ws_strlen(s); - size_t wlen = w2 - pl->s; - ws_strncpy(buf, s, wlen); - buf[wlen] = wc_null; - ws_memmove(s, s+wlen+1, slen-wlen-1); - *s = wc_toupper(*s); - *(s+slen-wlen-1) = wc_comma; - *(s+slen-wlen) = wc_tilda; - ws_strcpy(s+slen-wlen+1, buf); - return 1; - } - return 0; -} - -/* getstartchar(<string>,<default>) - * Returns the first non-escaped, alphabetic character of <string>. If - * <string> has no non-escaped, alphabetic characters, <default> is returned - * instead. */ -static WCHAR -getstartchar(s,def) - const WCHAR *s; - WCHAR def; -{ - if (!s) return def; - skipesc(&s); - while ((*s!=wc_null) && !wc_isalpha(*s)) - { - ++s; - skipesc(&s); - } - return (*s!=wc_null) ? wc_toupper(*s) : def; -} - -/* freesongarray(<array>,<len>) - * Free song array <array>, which should have length <len>. */ -static void -freesongarray(songs,len) - SONGENTRY **songs; - int len; -{ - int i; - - if (!songs) return; - for (i=0; i<len; ++i) - { - if (songs[i]) - { - if (songs[i]->title) free(songs[i]->title); - if (songs[i]->num) free(songs[i]->num); - if (songs[i]->linkname) free(songs[i]->linkname); - free(songs[i]); - } - } - free(songs); -} - -/* gentitleindex(<file>,<outname>) - * Reads a title index data file from file handle <file> and generates a new - * file named <outfile> containing a LaTeX title index. - * Return Value: 0 on success, 1 on warnings, or 2 on failure */ -int -gentitleindex(fs,outname) - FSTATE *fs; - const char *outname; -{ - FILE *f; - int eof = 0; - int numsongs, arraysize, i; - PREFIX *prelist = &pre_defaults; - SONGENTRY **songs; - WCHAR buf[MAXLINELEN], *bp; - WCHAR startchar; - - fprintf(stderr, "songidx: Parsing title index data file %s...\n", - fs->filename); - - songs = NULL; - eof = 0; - for (arraysize=numsongs=0; !eof; ++numsongs) - { - if (!filereadln(fs,buf,&eof)) - { - freesongarray(songs,numsongs); - return 2; - } - if (eof) break; - if (buf[0] == wc_percent) - { - if (!ws_strncmp(buf, wc_lit("%prefix "), 8)) - { - PREFIX *temp = (prelist==&pre_defaults) ? NULL : prelist; - prelist = (PREFIX *) malloc(sizeof(PREFIX)); - prelist->next = temp; - prelist->s = (WCHAR *) calloc(ws_strlen(buf)-7, sizeof(WCHAR)); - ws_strcpy(prelist->s, buf+8); - } - --numsongs; - continue; - } - if (numsongs >= arraysize) - { - SONGENTRY **temp; - arraysize *= 2; - if (arraysize==0) arraysize=64; - temp = (SONGENTRY **) realloc(songs,arraysize*sizeof(SONGENTRY *)); - if (!temp) - { - fprintf(stderr, "songidx:%s:%d: too many songs (out of memory)\n", - fs->filename, fs->lineno); - freeprefixes(prelist); - freesongarray(songs,numsongs); - return 2; - } - songs = temp; - } - if ((songs[numsongs] = (SONGENTRY *) malloc(sizeof(SONGENTRY))) == NULL) - { - fprintf(stderr, "songidx:%s:%d: too many songs (out of memory)\n", - fs->filename, fs->lineno); - freeprefixes(prelist); - freesongarray(songs,numsongs); - return 2; - } - songs[numsongs]->title = songs[numsongs]->num = - songs[numsongs]->linkname = NULL; - for (bp=buf+ws_strlen(buf)-1; (bp > buf) && wc_isspace(*bp); --bp) ; - if (wc_isspace(*bp)) *bp = wc_null; - for (bp=buf; wc_isspace(*bp); ++bp) ; - /* The following allocates one extra char of storage because we might add - * a comma later. */ - if ((songs[numsongs]->title = - (WCHAR *) calloc(ws_strlen(bp)+2, sizeof(WCHAR))) == NULL) - { - fprintf(stderr, "songidx:%s:%d: too many songs (out of memory)\n", - fs->filename, fs->lineno); - freeprefixes(prelist); - freesongarray(songs,numsongs+1); - return 2; - } - ws_strcpy(songs[numsongs]->title, bp); - rotate(songs[numsongs]->title, prelist); - if (!filereadln(fs,buf,&eof)) - { - freeprefixes(prelist); - freesongarray(songs,numsongs+1); - return 2; - } - if (eof) - { - fprintf(stderr, "songidx:%s:%d: incomplete song entry (orphan title)\n", - fs->filename, fs->lineno); - freeprefixes(prelist); - freesongarray(songs,numsongs+1); - return 2; - } - if ((songs[numsongs]->num = - (WCHAR *) calloc(ws_strlen(buf)+1, sizeof(WCHAR))) == NULL) - { - fprintf(stderr, "songidx:%s:%d: too many songs (out of memory)\n", - fs->filename, fs->lineno); - freeprefixes(prelist); - freesongarray(songs,numsongs+1); - return 2; - } - ws_strcpy(songs[numsongs]->num, buf); - if (!filereadln(fs,buf,&eof)) - { - freeprefixes(prelist); - freesongarray(songs,numsongs+1); - return 2; - } - if (eof) - { - fprintf(stderr, "songidx:%s:%d: incomplete song entry" - " (missing hyperlink)\n", fs->filename, fs->lineno); - freeprefixes(prelist); - freesongarray(songs,numsongs+1); - return 2; - } - if ((songs[numsongs]->linkname = - (WCHAR *) calloc(ws_strlen(buf)+1, sizeof(WCHAR))) == NULL) - { - fprintf(stderr, "songidx:%s:%d: too many songs (out of memory)\n", - fs->filename, fs->lineno); - freeprefixes(prelist); - freesongarray(songs,numsongs); - return 2; - } - ws_strcpy(songs[numsongs]->linkname, buf); - songs[numsongs]->idx = numsongs; - } - fileclose(fs); - freeprefixes(prelist); - - /* Sort the song array */ - qsort(songs, numsongs, sizeof(*songs), songcmp); - - /* Write the sorted data out to the output file. */ - fprintf(stderr, "songidx: Generating title index TeX file %s...\n", outname); - if (strcmp(outname,"-")) - { - if ((f = fopen(outname, "w")) == NULL) - { - fprintf(stderr, "songidx: Unable to open %s for writing.\n", outname); - return 2; - } - } - else - { - f = stdout; - outname = "stdout"; - } - -#define TRYWRITE(x) \ - if (!(x)) \ - { \ - fprintf(stderr, "songidx:%s: write error\n", outname); \ - if (f == stdout) fflush(f); else fclose(f); \ - freesongarray(songs,numsongs); \ - return 2; \ - } - - startchar = 'A'; - if (numsongs>0) - { - startchar = getstartchar(songs[0]->title, wc_capA); - TRYWRITE((ws_fputs(ws_lit("\\begin{idxblock}{"), f) >= 0) && - (ws_fputc(startchar, f)==startchar)) - } - for (i=0; i<numsongs; ++i) - { - WCHAR c = getstartchar(songs[i]->title, startchar); - if ((i>0) && !ws_coll(songs[i]->title, songs[i-1]->title)) - { - TRYWRITE((ws_fputs(ws_lit("\\\\\\hyperlink{"), f) >= 0) && - (ws_fputs(songs[i]->linkname, f) >= 0) && - (ws_fputs(ws_lit("}{"), f) >= 0) && - (ws_fputs(songs[i]->num, f) >= 0) && - (ws_fputs(ws_lit("}"), f) >= 0)) - continue; - } - else - { - TRYWRITE(ws_fputs(ws_lit("}\n"), f) >= 0) - } - if (startchar != c) - { - startchar = c; - TRYWRITE((ws_fputs(ws_lit("\\end{idxblock}\n\\begin{idxblock}{"), f) >= 0) - && (ws_fputc(startchar, f)==startchar) - && (ws_fputs(ws_lit("}\n"), f) >= 0)) - } - if (songs[i]->title[0] == wc_asterisk) - { - TRYWRITE((ws_fputs(ws_lit("\\idxaltentry{"), f) >= 0) && - (ws_fputs(songs[i]->title+1, f) >= 0) && - (ws_fputs(ws_lit("}{\\hyperlink{"), f) >= 0) && - (ws_fputs(songs[i]->linkname, f) >= 0) && - (ws_fputs(ws_lit("}{"), f) >= 0) && - (ws_fputs(songs[i]->num, f) >= 0) && - (ws_fputs(ws_lit("}"), f) >= 0)) - } - else - { - TRYWRITE((ws_fputs(ws_lit("\\idxentry{"), f) >= 0) && - (ws_fputs(songs[i]->title, f) >= 0) && - (ws_fputs(ws_lit("}{\\hyperlink{"), f) >= 0) && - (ws_fputs(songs[i]->linkname, f) >= 0) && - (ws_fputs(ws_lit("}{"), f) >= 0) && - (ws_fputs(songs[i]->num, f) >= 0) && - (ws_fputs(ws_lit("}"), f) >= 0)) - } - } - TRYWRITE(ws_fputs(ws_lit("}\n\\end{idxblock}\n"), f) >= 0) - -#undef TRYWRITE - - if (f == stdout) fflush(f); else fclose(f); - freesongarray(songs,numsongs); - return 0; -} |