/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#if (defined(_WIN32) || defined(_MSDOS) || defined(__IBMC__))
#include <io.h>
#else
#include <unistd.h>
#endif

#include "cpp.h"

#if defined MACOSX || !defined HAVE_GETOPT
extern int stgetopt(int, char *const *, const char *);
extern char *optarg;
extern int optind;
#else
#include <getopt.h>
#endif

extern char rcsid[];

int Pflag = 0;                          /* print no line information */
int Iflag = 0;							/* print includes */
int Mflag = 0;                          /* print macor expansion */
int Aflag = 0;                          /* translate character sets */
int Xflag = 0;                          /* print pragma for include/import */
int Vflag = 0;                          /* verbose flag */
int Cflag = 0;                          /* do not remove any comments */
int Dflag = 0;                          /* add parameter check to delete op */
int Cplusplus = 0;

extern void setup_kwtab(void);

void
    setup(int argc, char **argv)
{
    int c, fd, i, n;
    char *fp, *dp;
    Tokenrow tr;

    setup_kwtab();
#if defined MACOSX || !defined HAVE_GETOPT
    while ((c = stgetopt(argc, argv, "NOPV:I:D:U:F:A:X:u:l:+")) != -1)
#else
    while ((c = getopt(argc, argv, "NOPV:I:D:U:F:A:X:u:l:+")) != -1)
#endif
        switch (c)
        {
            case 'N':
                for (i = 0; i < NINCLUDE; i++)
                    if (includelist[i].always == 1)
                        includelist[i].deleted = 1;
                break;

            case 'I':
                for (i = NINCLUDE - 2; i >= 0; i--)
                {
                    if (includelist[i].file == NULL)
                    {
                        includelist[i].always = 1;
                        includelist[i].file = optarg;
                        break;
                    }
                }
                if (i < 0)
                    error(FATAL, "Too many -I directives");
                break;

            case 'D':
            case 'U':
            case 'A':
                setsource("<cmdarg>", -1, -1, optarg, 0);
                maketokenrow(3, &tr);
                gettokens(&tr, 1);
                doadefine(&tr, c);
                unsetsource();
                break;

            case 'P':                   /* Lineinfo */
                Pflag++;
                break;

            case 'V':
				for (n = 0; (c = optarg[n]) != '\0'; n++)
					switch (c)
					{
						case 'i':
							Iflag++;
							break;

						case 'm':
			                Mflag = 1;
							break;

						case 'x':
			                Mflag = 2;
							break;

						case 't':
							Vflag++;
							break;

						case 'v':
			                fprintf(stderr, "%s %s\n", argv[0], rcsid);
							break;

						default:
							error(WARNING, "Unknown verbose option %c", c);
					}
				break;

            case 'X':
				for (n = 0; (c = optarg[n]) != '\0'; n++)
					switch (c)
					{
						case 'a':
							Aflag++;
							break;

						case 'i':
							Xflag++;
							break;

						case 'c':
							Cflag++;
							break;

						case 'd':
							Dflag++;
							break;

						case 'w':
							dp = &optarg[n + 1];
							n += strlen(dp);
							while (isspace(*dp)) dp++;

							for (i = NINCLUDE - 1; i >= 0; i--)
							{
								if (wraplist[i].file == NULL)
								{
									wraplist[i].file = dp;
									break;
								}
							}
							if (i < 0)
								error(WARNING, "Too many -Xw directives");
							break;

						default:
							error(WARNING, "Unknown extension option %c", c);
					}
				break;

            case '+':
                Cplusplus++;
                break;

            case 'u':                   /* -undef fuer GCC (dummy) */
            case 'l':                   /* -lang-c++ fuer GCC (dummy) */
                break;

            default:
                break;
        }
    dp = ".";
    fp = "<stdin>";
    fd = 0;
    if (optind < argc)
    {
        if ((fp = strrchr(argv[optind], '/')) != NULL)
        {
            int len = fp - argv[optind];

            dp = (char *) newstring((uchar *) argv[optind], len + 1, 0);
            dp[len] = '\0';
        }
        fp = (char *) newstring((uchar *) argv[optind], strlen(argv[optind]), 0);
        if ((fd = open(fp, O_RDONLY)) <= 0)
            error(FATAL, "Can't open input file %s", fp);
    }

    if (optind + 1 < argc)
    {
        int fdo = creat(argv[optind + 1], 0666);

        if (fdo < 0)
            error(FATAL, "Can't open output file %s", argv[optind + 1]);

        dup2(fdo, 1);
    }
    includelist[NINCLUDE - 1].always = 0;
    includelist[NINCLUDE - 1].file = dp;
    setsource(fp, -1, fd, NULL, 0);
}


/* memmove is defined here because some vendors don't provide it at
   all and others do a terrible job (like calling malloc) */

#if !defined(__IBMC__) && !defined(_WIN32) && !defined(__GLIBC__) && !defined(__clang__)

void *
    memmove(void *dp, const void *sp, size_t n)
{
    unsigned char *cdp, *csp;

    if (n <= 0)
        return 0;
    cdp = dp;
    csp = (unsigned char *) sp;
    if (cdp < csp)
    {
        do
        {
            *cdp++ = *csp++;
        } while (--n);
    }
    else
    {
        cdp += n;
        csp += n;
        do
        {
            *--cdp = *--csp;
        } while (--n);
    }
    return 0;
}

#endif
