/* amiga.c
 * support routines for mkid to make Lattice (and probably Aztec) work
 * properly on the amiga
 *
 * Written by Randell Jesup, Commodore-Amiga Inc (before I came here).
 * This routine is public domain.
 */

#include <stdio.h>

/* fseek() on the amiga stops at end of file, instead of extending it */

#ifdef fseek	/* so I can #define fseek unixfseek */
#undef fseek
#endif

int
unixfseek (fp,rpos,mode)
	FILE *fp;
	long rpos;
	int mode;
{
	long oldpos = 0,newpos,endpos;

	if (mode == 1 && (oldpos = ftell(fp)) == -1L)
		return -1;

	if (fseek(fp,rpos,mode) == 0)
		return 0;	/* fseek succeeded - returns -1 if past end */

	if ((newpos = ftell(fp)) == -1L)
		return 0;	/* this is wierd, but fseek didn't error */

	switch (mode) {
	case 2:	/* no extension possible */
		return 0;
	case 1:
	case 0:
		if (newpos == oldpos + rpos)	/* if mode = 0, oldpos = 0 */
			return 0;
		break;	/* may need to extend */
	default:
		return -1;
	}

	/* since we got here, we didn't get where we thought */
	/* see if file needs extending */
	if (mode == 1 && rpos <= 0)	/* if negative seek, ignore */
		return 0;		/* might be seek to < 0     */

	if (fseek(fp,0L,2) == -1)	/* to end of file */
		return -1;

	if ((endpos = ftell(fp)) == -1L)
		return -1;

	if (endpos >= oldpos + rpos)	/* if mode = 0, oldpos = 0 */
		return 0;

	/* EXTEND! (albeit slowly - I don't care enough) */
	do {
		(void) putc('\0',fp);
/*		fseek(fp,0L,2);
 *		endpos = ftell(fp);
 */
	} while (++endpos < oldpos + rpos);	/* if ftell above, no ++ */

        return fseek(fp,rpos,mode);
}

/*
**	expand_args.c
**
**		Expands wild card arguments found in the command line.
**		Written by Olaf Barthel <olsen@sourcery.han.de>
**		Public Domain
*/

#include <dos/dosextens.h>
#include <dos/dosasl.h>

#include <exec/memory.h>

#include <clib/exec_protos.h>
#include <clib/dos_protos.h>

#include <pragmas/exec_pragmas.h>
#include <pragmas/dos_pragmas.h>

#include <stdlib.h>
#include <string.h>

#define MAX_FILENAME_LEN 512

typedef struct NameNode
{
	struct NameNode	*Next;
	char		*Name;
} *pNameNode, NameNode;

extern struct ExecBase		*SysBase;
extern struct DosLibrary	*DOSBase;

int
expand_args(int argc,char **argv,int *_argc,char ***_argv)
{
	NameNode		*Root		= NULL;
	LONG			 NamePlus	= 0;
	LONG			 NameTotal	= 0;
	LONG			 Error		= 0;
	struct AnchorPath	*Anchor;

	*_argc = argc;
	*_argv = argv;

	if(DOSBase -> dl_lib . lib_Version < 37)
		return(0);

	if(Anchor = (struct AnchorPath *)AllocVec(sizeof(struct AnchorPath) + MAX_FILENAME_LEN,MEMF_ANY | MEMF_CLEAR))
	{
		int i;

		Anchor -> ap_Strlen	= MAX_FILENAME_LEN;
		Anchor -> ap_BreakBits	= SIGBREAKF_CTRL_C;

		for(i = 0 ; !Error && i < argc ; i++)
		{
			if(i && ParsePatternNoCase(argv[i],Anchor -> ap_Buf,MAX_FILENAME_LEN) == 1)
			{
				NameNode	*Node;
				LONG		 Result;

				Result = MatchFirst(argv[i],Anchor);

				while(!Result)
				{
					if(Anchor -> ap_Info . fib_DirEntryType < 0)
					{
						if(Node = (NameNode *)malloc(sizeof(NameNode) + strlen(Anchor -> ap_Buf) + 1))
						{
							strcpy(Node -> Name = (char *)(Node + 1),Anchor -> ap_Buf);

							Node -> Next = Root;

							Root = Node;

							NamePlus++;
							NameTotal++;
						}
						else
						{
							Result = ERROR_NO_FREE_STORE;
							break;
						}
					}

					Result = MatchNext(Anchor);
				}

				if(Result != ERROR_NO_MORE_ENTRIES)
					Error = Result;
			}
			else
			{
				NameNode *Node;

				if(Node = (NameNode *)malloc(sizeof(NameNode)))
				{
					Node -> Name = argv[i];

					Node -> Next = Root;

					Root = Node;

					NameTotal++;
				}
				else
					Error = ERROR_NO_FREE_STORE;
			}
		}

		if(!Error && NamePlus)
		{
			char **Index;

			if(Index = (char **)malloc(sizeof(char *) * (NameTotal + 1)))
			{
				NameNode *Node;

				*_argc = NameTotal;
				*_argv = Index;

				Index = &(Index[NameTotal]);

				*Index-- = NULL;

				Node = Root;

				while(Node)
				{
					*Index-- = Node -> Name;

					Node = Node -> Next;
				}
			}
			else
				Error = ERROR_NO_FREE_STORE;
		}

		if(Error || !NamePlus)
		{
			NameNode *Node,*Next;

			Node = Root;

			while(Node)
			{
				Next = Node -> Next;

				free(Node);

				Node = Next;
			}
		}

		FreeVec(Anchor);
	}
	else
		Error = ERROR_NO_FREE_STORE;

	if(Error)
	{
		PrintFault(Error,argv[0]);

		return(-1);
	}
	else
		return(0);
}
