[Mew-dist 14652] Re: borland C

Tatsuya Kinoshita tatsuyak at example.com
2000年 10月 19日 (木) 02:28:14 JST


In message "[Mew-dist 14650] borland C"
Kazu Yamamoto (山本和彦) <kazu at example.com> wrote:

> Borland C には getopt() がなかったので、神戸さんのを使おうと思ったら、
> 4 つ項目のある BSD ライセンスだったので、利用を諦めました。結局今作り
> 直しています。

long optionが使えなくてかまわないなら、手元にpublic domainのもの
があります。

手遅れかもしれませんが、投げておきます。

-- 
木下達也 (Tatsuya Kinoshita)
-------------- next part --------------
/*
 * PROJECT C Library, X68000 PROGRAMMING INTERFACE DEFINITION
 * --------------------------------------------------------------------
 * This file is written by the Project C Library Group,  and completely
 * in public domain. You can freely use, copy, modify, and redistribute
 * the whole contents, without this notice.
 * --------------------------------------------------------------------
 * $Id: getopt.c,v 1.2 1993/11/13 06:35:08 mura Exp $
 */

/* System headers */
#include <stdio.h>
#include <stdlib.h>

char *optarg;							/* 引数を指すポインタ */
int optind = -1;						/* ARGV の現在のインデックス */
int opterr = 1;							/* エラー表示フラグ */
int _getopt_no_ordering;					/* ORDER フラグ */

/* File scope functions */
static void rotate_right (char *vector[], int size)
{
    char *temp;

    /* 最後尾を保存 */
    temp = vector[size - 1];

    /* size 分ローテート */
    while (size--)
	vector[size] = vector[size - 1];

    /* 先頭に保存していたものを... */
    vector[0] = temp;
}

/* Functions */
int getopt (int argc, char *argv[], const char *options)
{
    int index;							/* 現在のインデックス */
    int next;							/* 次のインデックス */
    int optchar;						/* オプション文字 */
    char *string;						/* オプション文字列 */
    const char *ptr;						/* options 探査用 */

    static int init;						/* 次回初期化する必要あり */
    static int savepoint;					/* 入れ換え用の記憶ポイント */
    static int rotated;						/* 交換フラグ */
    static int comidx;						/* 複合インデックス */

#define ERR if (opterr) fprintf

    /* 初期化の必要があれば初期化する */
    if (init || optind < 0) {
	optind = 1;
	optarg = 0;
	rotated = 0;
	init = 0;
	comidx = 1;
	savepoint = 0;
    }

    /* 捜査開始位置を設定 */
    index = optind;

  again:

    /* 引数を取り出す */
    string = argv[index];
    next = index + 1;

    /* すでに終りか? */
    if (string == 0) {
	if (savepoint > 0)
	    optind = savepoint;
	init = 1;
	return EOF;
    }

    /* '-' で始まるか? */
    if (*string == '-') {

	/* フラグ分ポインタを進める */
	string += comidx;

	/* 正確に "-" か?ならば普通の引数 */
	if ((optchar = *string++) == '\0')
	    goto normal_arg;

	/* ORDERING の必要があれば引数列を部分的にローテート */
	if (savepoint > 0) {
	    rotate_right (&argv[savepoint], index - savepoint + 1);
	    rotated = 1;
	    index = savepoint;
	    savepoint++;
	}

	/* 正確に "--" ならば強制的に捜査を終りにする */
	if (optchar == '-' && *string == '\0' && comidx == 1) {
	    init = 1;
	    optchar = EOF;
	    goto goback;
	}

	/* オプション文字群の中から該当するものがあるか調べる */
	for (ptr = options; *ptr; ptr++)
	    if (*ptr != ':' && *ptr == optchar)
		break;

	/* 引数を伴う場合ならばインデックスは初期化 */
	if (*string == '\0' || ptr[1] == ':')
	    comidx = 1;

	/* さもなければ複合オプションインデックスを加算 */
	else {
	    comidx++;
	    index--;
	}

	/* 結局見つからなかったなら... */
	if (*ptr == '\0') {
	    ERR (stderr, "%s: unrecognized option '-%c'\n", argv[0], optchar);
	    optchar = '?';
	}

	/* 見つかったがオプション指定に ':' があるなら... */
	else if (ptr[1] == ':') {

	    /* 同じ argv 内に引数があるか */
	    if (*string)
		optarg = string;

	    /* 次の引数にあるか */
	    else if (argv[next]) {

		/* ORDERING の必要があれば部分的に入れ換える */
		if (rotated) {
		    rotate_right (&argv[savepoint], next - savepoint + 1);
		    index = savepoint;
		}

		/* なければ... */
		else
		    index++;

		/* 次の引数を返す */
		optarg = argv[index];

	    }

	    /* なければ... */
	    else {
		ERR (stderr, "%s: option '-%c' requires an argument\n", argv[0], optchar);
		optchar = '?';
	    }

	}

      goback:

	/* 値を設定して戻る */
	rotated = 0;
	savepoint = 0;
	optind = index + 1;
	return optchar;

    }

    /* 普通の引数 */
    else {

      normal_arg:

	/* ORDERING する必要があるか? */
	if (_getopt_no_ordering) {
	    init = 1;
	    optind = index;
	    return EOF;
	}

	/* 引数の位置を記憶し、次のオプションを調べる */
	else {
	    if (savepoint == 0)
		savepoint = index;
	    index++;
	    goto again;
	}

    }
}
-------------- next part --------------
/*
 * getopt.h
 *
 * This work is written by Tatsuya Kinoshita.  You can use, copy, 
 * distribute and/or modify it without restriction.
 */

#ifndef GETOPT_H_
#define GETOPT_H_

extern char *optarg;
extern int optind;
extern int opterr;
extern int _getopt_no_ordering;

int getopt (int argc, char *argv[], const char *options);

#endif


Mew-dist メーリングリストの案内