Path: sparky!uunet!cis.ohio-state.edu!pacific.mps.ohio-state.edu!linac!att!cbnewsm!cbnewsl!att-out!rutgers!sun-barr!west.West.Sun.COM!cronkite.Central.Sun.COM!sixgun.East.Sun.COM!newscan!verdelait!martin
From: mar...@sun.com (Martin Leclerc SE Sun Montreal)
Newsgroups: alt.sources
Subject: chord v1.2 - part 2/2
Message-ID: <1992Sep3.183652.6930@newscan.canada.sun.com>
Date: 3 Sep 92 18:36:52 GMT
Sender: n...@newscan.canada.sun.com
Reply-To: mar...@sun.com
Organization: Sun Microsystems du Canada
Lines: 989
Nntp-Posting-Host: verdelait.canada.sun.com
Archive-Name: chord v1.2 - part 2/2

#!/bin/sh
# This is part 02 of a multipart archive
# ============= songs/heaven ==============
if test ! -d 'songs'; then
    echo 'x - creating directory songs'
    mkdir 'songs'
fi
if test -f 'songs/heaven' -a X"$1" != X"-c"; then
	echo 'x - skipping songs/heaven (File already exists)'
else
echo 'x - extracting songs/heaven (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'songs/heaven' &&
X{title:Heaven}
X{st:Bryan Adams}
X[C]Oh, [Am]thinking about all our [G]younger years
XThere was [Dm]only you and [Am]me,
Xwe were [Dm]young and wild and [G]free
X
X[C]Now, [Am]nothing can take you a[G]way from me
XWe've been [Dm]down that road be[Am]fore
XBut that's [Dm]over now, you keep me [G]comin' back for more
X
X{start_of_chorus}
X[F]Baby you're [G]all that I [Am]want
XWhen you're [C]lying here in my [F]arms
X[F]I'm finding it [G]hard to be[Am]lieve we're in [G]heaven
X
X[F]And love is [G]all that I [Am]need
XAnd I [C]found it here in your [F]heart
X[F]It isn't too [G]hard to [Am]see we're in [G]heaven
X{end_of_chorus}
X
X[C]Oh, [Am]once in your life you [G]find someone
XWho will [Dm]turn your world a[Am]round
XBring you [Dm]up when you're feeling [G]down
X
X[C]Yeah, [Am]nothing could change what you [G]mean to me
XOh there's [Dm]lots that I could [Am]say
XBut just [Dm]hold me now, 'cause our [G]love will light the way
X
X{c: chorus}
X
X[Dm]I've been waiting for so [F]long
XFor [C]something to [Am]arrive
XFor [Dm]love to come a[G]long
X
X[Dm]Now our dreams are coming [F]true
XThrough the [C]good times and the [Am]bad
X[G]Yeah, I'll be standing there by you
X
X{c: chorus}
SHAR_EOF
chmod 0666 songs/heaven ||
echo 'restore of songs/heaven failed'
Wc_c="`wc -c < 'songs/heaven'`"
test 1158 -eq "$Wc_c" ||
	echo 'songs/heaven: original size 1158, current size' "$Wc_c"
fi
# ============= songs/you_ve_got_a_friend ==============
if test -f 'songs/you_ve_got_a_friend' -a X"$1" != X"-c"; then
	echo 'x - skipping songs/you_ve_got_a_friend (File already exists)'
else
echo 'x - extracting songs/you_ve_got_a_friend (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'songs/you_ve_got_a_friend' &&
X{title:You've got a friend}
X{st:Carol King}
XWhen you're [Em] down and [B7] troubled and you [Em] need some [B7] lovin' [Em] care
XAnd [Am] nothing, [D] nothing is going [G] right
X[F#m] Close your eyes and [B7] think of me and [Em] soon I [B7] will be [Em] there
XTo [Am] brighten up [D] even your darkest [Am] nights
X
X{start_of_chorus}
XYou just [G] call out my name, and you [C] know, wherever I am,
XI come [G] running to see you [Am] again [D7]
X[G] Winter spring summer or [G7] fall [C] all you got to do is [Am] call
XAnd I'll [C] be there, yes I [Am] will
X{end_of_chorus}
X
X[A] You've got a [G] friend
X
XIf the [Em] sky a[B7]bove you grows [Em] dark and [B7] full of [Em] clouds,
Xand [Am] that old north [D] wind begins to [G] blow
X[F#m] Keep your head [B7] togheter, and [Em] call my [B7] name out [Em] loud
X[Am] Soon you'll hear me [D] knocking at your [Am] door
X{c:chorus}
X[F] Now ain't it good to know that [C] you've got a friend
XWhen [G] people can be so [G7] cold
XThe'll [C] hurt you, yes and [Fm] desert you and [Em] take your soul if you [Am7] let them
XBut [A7] don't you let [D] them
X{c:chorus}
X[A] You've got a [G] friend. [D] You've got a [Em] friend
SHAR_EOF
chmod 0666 songs/you_ve_got_a_friend ||
echo 'restore of songs/you_ve_got_a_friend failed'
Wc_c="`wc -c < 'songs/you_ve_got_a_friend'`"
test 1161 -eq "$Wc_c" ||
	echo 'songs/you_ve_got_a_friend: original size 1161, current size' "$Wc_c"
fi
# ============= makefile.vms ==============
if test -f 'makefile.vms' -a X"$1" != X"-c"; then
	echo 'x - skipping makefile.vms (File already exists)'
else
echo 'x - extracting makefile.vms (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'makefile.vms' &&
Xchord : argproc.obj grid.obj iso.obj chord.obj
X   link /exe=chord.exe argproc.obj,chord.obj,grid.obj,iso.obj,sys$input/opt
Xsys$share:vaxcrtl.exe /share $
X
Xargproc.obj : argproc.c
X   cc argproc.c /obj=argproc.obj
X
Xchord.obj : chord.c
X   cc chord.c /obj=chord.obj
X
Xgrid.obj : grid.c
X   cc grid.c /obj=grid.obj
X
Xiso.obj : iso.c
X   cc iso.c /obj=iso.obj
X
SHAR_EOF
chmod 0644 makefile.vms ||
echo 'restore of makefile.vms failed'
Wc_c="`wc -c < 'makefile.vms'`"
test 351 -eq "$Wc_c" ||
	echo 'makefile.vms: original size 351, current size' "$Wc_c"
fi
# ============= chord.rnh ==============
if test -f 'chord.rnh' -a X"$1" != X"-c"; then
	echo 'x - skipping chord.rnh (File already exists)'
else
echo 'x - extracting chord.rnh (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'chord.rnh' &&
X.noflags accept
X.lm 1
X.rm 75
X.i-1;1 Chord
X.br
Xchord - format lyrics and chord file
X.br
X.i-1;2 Usage
X.br
XTo make the Chord utility available to your login session, you must first
Xeither issue the command:
X.bl
X.i+5;SETUP CHORD
X.bl
Xat the VMS $ prompt, or add the following line to your LOGIN.COM file:
X.bl
X.i+5;$ SETUP CHORD /QUIET
X.br
X.i-1;2 Synopsis
X.br
Xchord [-option ...] [ filename... ]
X.br
X.i-1;2 Description
X.br
Xchord produces a postscript document from a lyrics file containing chord
Xindications and chorus delimiters. If no file name is supplied, 
Xchordreads from the standard input.
XThe document produced contains the lyrics of a song, with the guitar chords
Xappearing above the right words. A representation of all chords used in the
Xsong is printed at the bottom of the last page.
X.br
X.i-1;2 Options
X.br
X-c chord_font size
X.bl
XSets the size, in points, of the font used to display chords to the specified
Xinteger value.
X.bl
X-C Chord_font
X.bl
XSets the font used to print chords to the specified name. That name must be
Xknown to your PostScript Interpreter.
X.bl
X-d
X.bl
XDumps the list and description of all internally known chords.
X.bl
X-D
X.bl
XPrints debugging information. For programmers only.
X.bl
X-h
X.bl
XPrints a short options summary.
X.bl
X-l
X.bl
XPrints only the lyrics of the song.
X.bl
X.bl
X-t text_font size
X.bl
XSets the size, in points, of the font used to display the lyrics to the
Xspecified integer value. The title
Xline is displayed using that point size + 5. The sub-tiltle is displayed
Xusing that point size -2.
X.bl
X-T Text_font
X.bl
XSets the font used to print text to the specified name. That name must be
Xknown to your PostScript Interpreter.
X.bl
X-2
X.bl
XPrints two logical pages per physical page.
X.bl
X-4
X.bl
XPrints four logical pages per physical page.
X.br
X.i-1;2 Keywords
X.br
XA line starting with a '#' is interpreted as a comment, and generates no output.
X(although all your comments are automatically mailed to the authors, and we read them
Xat parties...)
X.bl
XDirectives that  appear between french brackets ('{' and '}') have a
Xspecial meaning. They must be alone on a line. Blanks before the
Xopening bracket and after the closing bracket are not significant.
X.bl
XBlanks inside a directive are significant.
X.bl
XKnown directives are:
X.bl
Xstart_of_chorus or soc
X.bl
Xwhich indicates the start of a chorus (yep). The complete chorus will
Xbe highlighted by a change bar, to be easily located by the player.
X.bl
Xend_of_chorus or eoc
X.bl
Xmarks the end of the chorus
X.bl
Xcomment: or c:
X.bl
Xwill call the printing of the rest of the line, highlighted by a grey box
X(Useful to call a chorus, for example)
X.bl
Xnew_song or ns
X.bl
Xmarks the beginning of a new song. It enables you to put multiple songs
Xin one file. It is not required at the beginning of the file.
X.bl
Xtitle: or t:
X.bl
Xspecifies the title of the song. It will appear centered at the top of the first
Xpage, and at the bottom of every other page, accompanied there by the
Xpage number, within the current song.
X.bl
Xsubtitle: or t:
X.bl
Xspecifies a string to be printed right below the title. Many subtitles can be
Xspecified
X.bl
Xdefine: name offset str1 ... str6
X.bl
Xdefines a new chord called "name", starting at fret "offset".
XThe following numbers
Xare the fret number [ 1 to n ] for each string [str1 to str6]
Xand are RELATIVE to the offset.  A value of -1 as 
Xthe fret number on string X means that string X is to be buffed,
Xor silenced. This will be reprensented by
Xand "x" appearing on the corresponding string.
XThe strings are numbered in ascending order of tonality, starting on the
Xlow E (the top string).
X.bl
XAt the beginning of every song, the default chords are loaded and the ~/.chordrc
Xfile is re-read. Definition of new chords are preserved for the remainder of the
Xexecution, or until redefined by the user.
X.bl
Xtextfont: postscript_font
Xsame as -T command option
X.bl
Xtextsize: n
Xsame as -t command option
X.bl
Xchordfont: postscript_font
Xsame as -C command option
X.bl
Xchordsize: n
Xsame as -c command option
X.br
X.i-1;2 Copyright
X.br
XCopyright 1992 by Martin Leclerc and Mario Dorion
X.br
X.i-1;2 Authors
X.br
XMartin Leclerc
X.br
X(martin.lecl...@canada.sun.com)
X.bl
XMario Dorion
X.br
X(mario.dor...@canada.sun.com)
X.bl
XJim Gerland (VMS port)
X.br
X(gerl...@ubvms.cc.buffalo.edu)
X.br
X
SHAR_EOF
chmod 0644 chord.rnh ||
echo 'restore of chord.rnh failed'
Wc_c="`wc -c < 'chord.rnh'`"
test 4262 -eq "$Wc_c" ||
	echo 'chord.rnh: original size 4262, current size' "$Wc_c"
fi
# ============= argproc.c ==============
if test -f 'argproc.c' -a X"$1" != X"-c"; then
	echo 'x - skipping argproc.c (File already exists)'
else
echo 'x - extracting argproc.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'argproc.c' &&
X/*
XFrom GERL...@ubvms.cc.buffalo.edu Thu May 21 15:50:58 1992
XReturn-Path: <GERL...@ubvms.cc.buffalo.edu>
XDate: Thu, 21 May 1992 15:50 EST
XFrom: Jim Gerland - User Support Services <GERL...@ubvms.cc.buffalo.edu>
XSubject: Re: chord (for VMS)
XTo: Martin.Lecl...@Canada.Sun.COM
XX-Organization: University at Buffalo
XX-Envelope-To: Martin.Lecl...@Canada.Sun.COM
XX-Vms-To: IN%"Martin.Lecl...@Canada.Sun.COM"
XContent-Length: 13174
XX-Lines: 554
X*/
X
X/*
X * @(#)argproc.c 1.0 89/02/01		Mark Pizzolato (m...@infopiz.uucp)	
X */
X
X#ifndef lint
Xchar argproc_version[] = "@(#)argproc.c VMS uucp Version infopiz-1.0";
X#endif
X
X/* #include "includes.h"		/* System include files, system dependent */
X
X/*
X * getredirection() is intended to aid in porting C programs
X * to VMS (Vax-11 C) which does not support '>' and '<'
X * I/O redirection, along with a command line pipe mechanism
X * using the '|' AND background command execution '&'.
X * The piping mechanism will probably work with almost any 'filter' type
X * of program.  With suitable modification, it may useful for other
X * portability problems as well.
X *
X * Author:  Mark Pizzolato	m...@infopiz.UUCP
X */
Xstruct list_item
X    {
X    struct list_item *next;
X    char *value;
X    };
X
Xint
Xgetredirection(ac, av)
Xint		*ac;
Xchar		***av;
X/*
X * Process vms redirection arg's.  Exit if any error is seen.
X * If getredirection() processes an argument, it is erased
X * from the vector.  getredirection() returns a new argc and argv value.
X * In the event that a background command is requested (by a trailing "&"),
X * this routine creates a background subprocess, and simply exits the program.
X *
X * Warning: do not try to simplify the code for vms.  The code
X * presupposes that getredirection() is called before any data is
X * read from stdin or written to stdout.
X *
X * Normal usage is as follows:
X *
X *	main(argc, argv)
X *	int		argc;
X *    	char		*argv[];
X *	{
X *		getredirection(&argc, &argv);
X *	}
X */
X{
X    int			argc = *ac;	/* Argument Count	  */
X    char		**argv = *av;	/* Argument Vector	  */
X    char		*ap;   		/* Argument pointer	  */
X    int	       		j;		/* argv[] index		  */
X    extern int		errno;		/* Last vms i/o error 	  */
X    int			item_count = 0;	/* Count of Items in List */
X    struct list_item 	*list_head = 0;	/* First Item in List	    */
X    struct list_item	*list_tail;	/* Last Item in List	    */
X    char 		*in = NULL;	/* Input File Name	    */
X    char 		*out = NULL;	/* Output File Name	    */
X    char 		*outmode = "w";	/* Mode to Open Output File */
X    int			cmargc = 0;    	/* Piped Command Arg Count  */
X    char		**cmargv = NULL;/* Piped Command Arg Vector */
X    stat_t		statbuf;	/* fstat buffer		    */
X
X    /*
X     * First handle the case where the last thing on the line ends with
X     * a '&'.  This indicates the desire for the command to be run in a
X     * subprocess, so we satisfy that desire.
X     */
X    ap = argv[argc-1];
X    if (0 == strcmp("&", ap))
X	exit(background_process(--argc, argv));
X    if ('&' == ap[strlen(ap)-1])
X	{
X	ap[strlen(ap)-1] = '\0';
X	exit(background_process(argc, argv));
X	}
X    /*
X     * Now we handle the general redirection cases that involve '>', '>>',
X     * '<', and pipes '|'.
X     */
X    for (j = 0; j < argc; ++j)
X	{
X	if (0 == strcmp("<", argv[j]))
X	    {
X	    if (j+1 >= argc)
X		{
X		errno = EINVAL;
X		perror("No input file");
X		exit(EXIT_ERR);
X		}
X	    in = argv[++j];
X	    continue;
X	    }
X	if ('<' == *(ap = argv[j]))
X	    {
X	    in = 1 + ap;
X	    continue;
X	    }
X	if (0 == strcmp(">", ap))
X	    {
X	    if (j+1 >= argc)
X		{
X		errno = EINVAL;
X		perror("No output file");
X		exit(EXIT_ERR);
X		}
X	    out = argv[++j];
X	    continue;
X	    }
X	if ('>' == *ap)
X	    {
X	    if ('>' == ap[1])
X		{
X		outmode = "a";
X		if ('\0' == ap[2])
X		    out = argv[++j];
X		else
X		    out = 2 + ap;
X		}
X	    else
X		out = 1 + ap;
X	    continue;
X	    }
X	if (0 == strcmp("|", argv[j]))
X	    {
X	    if (j+1 >= argc)
X		{
X		errno = EPIPE;
X		perror("No command to Pipe to");
X		exit(EXIT_ERR);
X		}
X	    cmargc = argc-(j+1);
X	    cmargv = &argv[j+1];
X	    argc = j;
X	    continue;
X	    }
X	if ('|' == *(ap = argv[j]))
X	    {
X	    ++argv[j];
X	    cmargc = argc-j;
X	    cmargv = &argv[j];
X	    argc = j;
X	    continue;
X	    }
X	expand_wild_cards(ap, &list_head, &list_tail, &item_count);
X	}
X    /*
X     * Allocate and fill in the new argument vector, Some Unix's terminate
X     * the list with an extra null pointer.
X     */
X    argv = *av = calloc(item_count+1, sizeof(char *));
X    for (j = 0; j < item_count; ++j, list_head = list_head->next)
X	argv[j] = list_head->value;
X    *ac = item_count;
X    if (cmargv != NULL)
X	{
X	char subcmd[1024];
X	static char *pipe_and_fork();
X
X	if (out != NULL)
X	    {
X	    errno = EINVAL;
X	    perror("Invalid '|' and '>' specified");
X	    exit(EXIT_ERR);
X	    }
X	strcpy(subcmd, cmargv[0]);
X	for (j = 1; j < cmargc; ++j)
X	    {
X	    strcat(subcmd, " \"");
X	    strcat(subcmd, cmargv[j]);
X	    strcat(subcmd, "\"");
X	    }
X	out = pipe_and_fork(subcmd);
X	outmode = "wb";
X	}
X	
X    /* Check for input from a pipe (mailbox) */
X
X    if(fstat(0, &statbuf) == 0){
X	if(strncmp(statbuf.st_dev, "MB", 2) == 0 || 
X	    strncmp(statbuf.st_dev, "_MB", 3) == 0){
X
X	    /* Input from a pipe, reopen it in binary mode to disable	*/
X	    /* carriage control processing.				*/
X
X	    if (in != NULL){
X		errno = EINVAL;
X		perror("Invalid '|' and '<' specified");
X		exit(EXIT_ERR);
X		}
X	    freopen(statbuf.st_dev, "rb", stdin);
X	    }
X	}
X    else {
X	perror("fstat failed");
X	exit(EXIT_ERR);
X	}
X    if ((in != NULL) && (NULL == freopen(in, "r", stdin, "mbc=32", "mbf=2")))
X	{
X	perror(in);    	       	/* Can't find file		*/
X	exit(EXIT_ERR);		/* Is a fatal error		*/
X	}
X    if ((out != NULL) && (NULL == freopen(out, outmode, stdout, "mbc=32", "mbf=2")))
X	{	
X	perror(ap);		/* Error, can't write or append	*/
X	exit(EXIT_ERR);		/* Is a fatal error		*/
X	}
X#ifdef DEBUG
X    fprintf(stderr, "Arglist:\n");
X    for (j = 0; j < *ac;  ++j)
X	fprintf(stderr, "argv[%d] = '%s'\n", j, argv[j]);
X#endif
X}
X
Xstatic add_item(head, tail, value, count)
Xstruct list_item **head;
Xstruct list_item **tail;
Xchar *value;
Xint *count;
X{
X    if (*head == 0)
X	{
X	if (NULL == (*head = calloc(1, sizeof(**head))))
X	    {
X	    errno = ENOMEM;
X	    perror("");
X	    exit(EXIT_ERR);
X	    }
X	*tail = *head;
X	}
X    else
X	if (NULL == ((*tail)->next = calloc(1, sizeof(**head))))
X	    {
X	    errno = ENOMEM;
X	    perror("");
X	    exit(EXIT_ERR);
X	    }
X	else
X	    *tail = (*tail)->next;
X    (*tail)->value = value;
X    ++(*count);
X}
X
Xstatic expand_wild_cards(item, head, tail, count)
Xchar *item;
Xstruct ltem_list **head;
Xstruct ltem_list **tail;
Xint *count;
X{
Xint expcount = 0;
Xint context = 0;
Xint status;
Xint status_value;
Xint had_version;
X$DESCRIPTOR(filespec, item);
X$DESCRIPTOR(defaultspec, "SYS$DISK:[]*.*;");
X$DESCRIPTOR(resultspec, "");
X
X    if (strcspn(item, "*%") == strlen(item))
X	{
X	add_item(head, tail, item, count);
X	return;
X	}
X    resultspec.dsc$b_dtype = DSC$K_DTYPE_T;
X    resultspec.dsc$b_class = DSC$K_CLASS_D;
X    resultspec.dsc$a_pointer = NULL;
X    filespec.dsc$w_length = strlen(item);
X    /*
X     * Only return version specs, if the caller specified a version
X     */
X    had_version = strchr(item, ';');
X    while (1 == (1&lib$find_file(&filespec, &resultspec, &context,
X    				 &defaultspec, 0, &status_value, &0)))
X	{
X	char *string;
X	char *c;
X
X	if (NULL == (string = calloc(1, resultspec.dsc$w_length+1)))
X	    {
X	    errno = ENOMEM;
X	    perror("");
X	    exit(EXIT_ERR);
X	    }
X	strncpy(string, resultspec.dsc$a_pointer, resultspec.dsc$w_length);
X	string[resultspec.dsc$w_length] = '\0';
X	if (NULL == had_version)
X	    *((char *)strrchr(string, ';')) = '\0';
X	/*
X	 * Be consistent with what the C RTL has already done to the rest of
X	 * the argv items and lowercase all of these names.
X	 */
X	for (c = string; *c; ++c)
X	    if (isupper(*c))
X		*c = tolower(*c);
X	add_item(head, tail, string, count);
X	++expcount;
X	}
X    if (expcount == 0)
X	add_item(head, tail, item, count);
X    lib$sfree1_dd(&resultspec);
X    lib$find_file_end(&context);
X}
X
Xstatic int child_st[2];	/* Event Flag set when child process completes	*/
X
Xstatic short child_chan;/* I/O Channel for Pipe Mailbox			*/
X
Xstatic exit_handler(status)
Xint *status;
X{
Xshort iosb[4];
X
X    if (0 == child_st[0])
X	{
X#ifdef DEBUG
X	fprintf(stderr, "Waiting for Child Process to Finnish . . .\n");
X#endif
X	fflush(stdout);	    /* Have to flush pipe for binary data to	*/
X			    /* terminate properly -- <t...@mccall.com>	*/
X	sys$qiow(0, child_chan, IO$_WRITEOF, iosb, 0, 0, 0, 0, 0, 0, 0, 0);
X	sys$dassgn(child_chan);
X	fclose(stdout);
X	sys$synch(0, child_st);
X	}
X}
X
X/*
X#include syidef		/* System Information Definitions	*/
X*/
X
Xstatic sig_child(chan)
Xint chan;
X{
X#ifdef DEBUG
X    fprintf(stderr, "Child Completion AST\n");
X#endif
X    if (child_st[0] == 0)
X	child_st[0] = 1;
X}
X
Xstatic struct exit_control_block
X    {
X    struct exit_control_block *flink;
X    int	(*exit_routine)();
X    int arg_count;
X    int *status_address;
X    int exit_status;
X    } exit_block =
X    {
X    0,
X    exit_handler,
X    1,
X    &exit_block.exit_status,
X    0
X    };
X
Xstatic char *pipe_and_fork(cmd)
Xchar *cmd;
X{
X    $DESCRIPTOR(cmddsc, cmd);
X    static char mbxname[64];
X    $DESCRIPTOR(mbxdsc, mbxname);
X    short iosb[4];
X    int status;
X    int pid;
X    struct
X	{
X	short dna_buflen;
X	short dna_itmcod;
X	char *dna_buffer;
X	short *dna_retlen;
X	int listend;
X	} itmlst =
X	{
X	sizeof(mbxname),
X	DVI$_DEVNAM,
X	mbxname,
X	&mbxdsc.dsc$w_length,
X	0
X	};
X    int mbxsize;
X    struct
X	{
X	short mbf_buflen;
X	short mbf_itmcod;
X	int *mbf_maxbuf;
X	short *mbf_retlen;
X	int listend;
X	} syiitmlst =
X	{
X	sizeof(mbxsize),
X	SYI$_MAXBUF,
X	&mbxsize,
X	0,
X	0
X	};
X
X    cmddsc.dsc$w_length = strlen(cmd);
X    /*
X     * Get the SYSGEN parameter MAXBUF, and the smaller of it and 2048 as
X     * the size of the 'pipe' mailbox.
X     */
X    if (1 == (1&(vaxc$errno = sys$getsyiw(0, 0, 0, &syiitmlst, iosb, 0, 0, 0))))
X	vaxc$errno = iosb[0];
X    if (0 == (1&vaxc$errno))
X	{
X 	errno = EVMSERR;
X	perror("Can't get SYSGEN parameter value for MAXBUF");
X	exit(EXIT_ERR);
X	}
X    if (mbxsize > 2048)
X	mbxsize = 2048;
X    if (0 == (1&(vaxc$errno = sys$crembx(0, &child_chan, mbxsize, mbxsize, 0, 0, 0))))
X	{
X	errno = EVMSERR;
X	perror("Can't create pipe mailbox");
X	exit(EXIT_ERR);
X	}
X    if (1 == (1&(vaxc$errno = sys$getdviw(0, child_chan, 0, &itmlst, iosb,
X    					  0, 0, 0))))
X	vaxc$errno = iosb[0];
X    if (0 == (1&vaxc$errno))
X	{
X 	errno = EVMSERR;
X	perror("Can't get pipe mailbox device name");
X	exit(EXIT_ERR);
X	}
X    mbxname[mbxdsc.dsc$w_length] = '\0';
X#ifdef DEBUG
X    fprintf(stderr, "Pipe Mailbox Name = '%s'\n", mbxname);
X#endif
X    if (0 == (1&(vaxc$errno = lib$spawn(&cmddsc, &mbxdsc, 0, &1,
X    					0, &pid, child_st, &0, sig_child,
X    					&child_chan))))
X	{
X	errno = EVMSERR;
X	perror("Can't spawn subprocess");
X	exit(EXIT_ERR);
X	}
X#ifdef DEBUG
X    fprintf(stderr, "Subprocess's Pid = %08X\n", pid);
X#endif
X    sys$dclexh(&exit_block);
X    return(mbxname);
X}
X
Xbackground_process(argc, argv)
Xint argc;
Xchar **argv;
X{
Xchar command[2048] = "$";
X$DESCRIPTOR(value, command);
X$DESCRIPTOR(cmd, "BACKGROUND$COMMAND");
X$DESCRIPTOR(null, "NLA0:");
Xint pid;
X
X    strcat(command, argv[0]);
X    while (--argc)
X	{
X	strcat(command, " \"");
X	strcat(command, *(++argv));
X	strcat(command, "\"");
X	}
X    value.dsc$w_length = strlen(command);
X    if (0 == (1&(vaxc$errno = lib$set_symbol(&cmd, &value))))
X	{
X	errno = EVMSERR;
X	perror("Can't create symbol for subprocess command");
X	exit(EXIT_ERR);
X	}
X    if (0 == (1&(vaxc$errno = lib$spawn(&cmd, &null, 0, &17, 0, &pid))))
X	{
X	errno = EVMSERR;
X	perror("Can't spawn subprocess");
X	exit(EXIT_ERR);
X	}
X#ifdef DEBUG
X    fprintf(stderr, "%s\n", command);
X#endif
X    fprintf(stderr, "%08X\n", pid);
X    return(EXIT_OK);
X}
X/* got this off net.sources */
X
X#ifdef	VMS
X#define	index	strchr
X#endif	/*VMS*/
X
X/*
X * get option letter from argument vector
X */
Xint	opterr = 1,		/* useless, never set or used */
X	optind = 1,		/* index into parent argv vector */
X	optopt;			/* character checked for validity */
Xchar	*optarg;		/* argument associated with option */
X
X#define BADCH	(int)'?'
X#define EMSG	""
X#define tell(s)	fputs(progname,stderr);fputs(s,stderr); \
X		fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);
X
Xgetopt(nargc,nargv,ostr)
Xint	nargc;
Xchar	**nargv,
X	*ostr;
X{
X	static char	*place = EMSG;	/* option letter processing */
X	register char	*oli;		/* option letter list index */
X	char	*index();
X	char	*progname;
X
X	if(!*place) {			/* update scanning pointer */
X		if(optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) return(EOF);
X		if (*place == '-') {	/* found "--" */
X			++optind;
X			return(EOF);
X		}
X	}				/* option letter okay? */
X	if ((optopt = (int)*place++) == (int)':' || !(oli = index(ostr,optopt))) {
X		if(!*place) ++optind;
X#ifdef VMS
X                progname = strrchr(nargv[0],']');
X#else
X                progname = rindex(nargv[0],'/');
X#endif
X                if (!progname) progname = nargv[0]; else progname++;
X		tell(": illegal option -- ");
X	}
X	if (*++oli != ':') {		/* don't need argument */
X		optarg = NULL;
X		if (!*place) ++optind;
X	}
X	else {				/* need an argument */
X		if (*place) optarg = place;	/* no white space */
X		else if (nargc <= ++optind) {	/* no arg */
X			place = EMSG;
X#ifdef VMS
X                        progname = strrchr(nargv[0],']');
X#else
X                        progname = rindex(nargv[0],'/');
X#endif
X                        if (!progname) progname = nargv[0]; else progname++;
X			tell(": option requires an argument -- ");
X		}
X	 	else optarg = nargv[optind];	/* white space */
X		place = EMSG;
X		++optind;
X	}
X	return(optopt);			/* dump back option letter */
X}
X
SHAR_EOF
chmod 0644 argproc.c ||
echo 'restore of argproc.c failed'
Wc_c="`wc -c < 'argproc.c'`"
test 13622 -eq "$Wc_c" ||
	echo 'argproc.c: original size 13622, current size' "$Wc_c"
fi
# ============= README ==============
if test -f 'README' -a X"$1" != X"-c"; then
	echo 'x - skipping README (File already exists)'
else
echo 'x - extracting README (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'README' &&
XThis is a description of a utility called 'chord'.
X
XIt's purpose is to provide guitar players with a tool to produce good looking,
Xself-descriptive music sheet from a text file.
X
X'chord' read a text file containing the lyrics of a song, the chords to be played,
Xtheir description and some other optional data to produce a PostScript document
Xthat includes:
X	
X	Centered titles
X	Chord names above the words
X	Graphical representation of the chords at the end of the songs
X
X'chord' also provides support for 
X
X	Multiple logical pages per physical pages ( 1, 2 or 4)
X	Configurable fonts for the lyrics and the chord names
X	Multiple songs inside one file
X	The complete ISO 8859-1 character set
Xand
X	Chorus marking
X
XNEW IN VERSION 1.2
X
Xo More flexible Page Numbering
X  o Left/right
X  o always-present
X  o an option for simgle spacing on lines with no chords
Xo Distinction between an unplayed string and a buffed one
Xo TOC generation
Xo Some bug fixes
X
XThanks to contributor Steve Putz !
X
XNEW IN VERSION 1.1
X
Xo 'chord' supports transposition. See the man page.
Xo miscellanious bug fixes, including dubious coding that kept IBM and SGI from
X  executing chord properly
Xo the grids now indicate string played open
Xo Error messages noe correctly report the name of the file and
X  the line number where the error was found
X
XPLANNED
X
Xo Support for tablature
Xo Alternate marking for the chorus
X
X
X'chord' has been developped on SPARCStations running SunOS 4.1.2 and
XOpenWindows 3. The PostScript previewer (PageView), SparcPrinters and
XLaserWriter II have had no problem with the output. Please report any
Xchanges your system requires.
X
X===== COMPILING =====
X
Xchord is written in fairly portable C and should work on most UNIX
Xsystems with little or no change. Let us know of your problems.
X
XSimply edit the Makefile to meet your environment and 'make'
X
X===== Amiga =====
X
XChord was successfully compled on an amiga system using a PD getopts
X
X
X===== VMS =====
X
XVMS port was done by  Jim Gerland (GERL...@ubvms.cc.buffalo.edu)
X	chord.rnh
X	makefile.vms
X	argproc.c
X
X===== ARCHIVES =====
X
XJames B. from the University of Nevada (nevada.edu) has
Xgraciously open the doors of their ftp site for archiving
Xsongs in chord format. Look under /pub/guitar/CHORD, and be polite.
X
X
XMartin Leclerc (Martin.Lecl...@canada.sun.com)
XMario Dorion   (Mario.Dor...@canada.sun.com)	
SHAR_EOF
chmod 0644 README ||
echo 'restore of README failed'
Wc_c="`wc -c < 'README'`"
test 2345 -eq "$Wc_c" ||
	echo 'README: original size 2345, current size' "$Wc_c"
fi
exit 0
