111894Speter/* RCS keyword table and match operation */
29Sjkh
311894Speter/* Copyright 1982, 1988, 1989 Walter Tichy
411894Speter   Copyright 1990, 1991, 1992, 1993, 1995 Paul Eggert
59Sjkh   Distributed under license by the Free Software Foundation, Inc.
69Sjkh
79SjkhThis file is part of RCS.
89Sjkh
99SjkhRCS is free software; you can redistribute it and/or modify
109Sjkhit under the terms of the GNU General Public License as published by
119Sjkhthe Free Software Foundation; either version 2, or (at your option)
129Sjkhany later version.
139Sjkh
149SjkhRCS is distributed in the hope that it will be useful,
159Sjkhbut WITHOUT ANY WARRANTY; without even the implied warranty of
169SjkhMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
179SjkhGNU General Public License for more details.
189Sjkh
199SjkhYou should have received a copy of the GNU General Public License
2011894Speteralong with RCS; see the file COPYING.
2111894SpeterIf not, write to the Free Software Foundation,
2211894Speter59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
239Sjkh
249SjkhReport problems and direct all questions to:
259Sjkh
269Sjkh    rcs-bugs@cs.purdue.edu
279Sjkh
289Sjkh*/
299Sjkh
3011894Speter/*
3111894Speter * Revision 5.4  1995/06/16 06:19:24  eggert
3211894Speter * Update FSF address.
338858Srgrimes *
3411894Speter * Revision 5.3  1993/11/03 17:42:27  eggert
3511894Speter * Add Name keyword.
361764Srgrimes *
379Sjkh * Revision 5.2  1991/08/19  03:13:55  eggert
389Sjkh * Say `T const' instead of `const T'; it's less confusing for pointer types.
399Sjkh * (This change was made in other source files too.)
409Sjkh *
419Sjkh * Revision 5.1  1991/04/21  11:58:25  eggert
429Sjkh * Don't put , just before } in initializer.
439Sjkh *
449Sjkh * Revision 5.0  1990/08/22  08:12:54  eggert
459Sjkh * Add -k.  Ansify and Posixate.
469Sjkh *
479Sjkh * Revision 4.3  89/05/01  15:13:02  narten
489Sjkh * changed copyright header to reflect current distribution rules
498858Srgrimes *
509Sjkh * Revision 4.2  87/10/18  10:36:33  narten
519Sjkh * Updating version numbers. Changes relative to 1.1 actuallyt
529Sjkh * relative to 4.1
538858Srgrimes *
549Sjkh * Revision 1.2  87/09/24  14:00:10  narten
558858Srgrimes * Sources now pass through lint (if you ignore printf/sprintf/fprintf
569Sjkh * warnings)
578858Srgrimes *
589Sjkh * Revision 4.1  83/05/04  10:06:53  wft
599Sjkh * Initial revision.
608858Srgrimes *
619Sjkh */
629Sjkh
639Sjkh
649Sjkh#include "rcsbase.h"
659Sjkh
6650472SpeterlibId(keysId, "$FreeBSD$")
679Sjkh
689Sjkh
6925699Speterchar const *Keyword[] = {
709Sjkh    /* This must be in the same order as rcsbase.h's enum markers type. */
7111894Speter	0,
729Sjkh	AUTHOR, DATE, HEADER, IDH,
7325699Speter	LOCKER, LOG, NAME, RCSFILE, REVISION, SOURCE, STATE, CVSHEADER,
7425699Speter	NULL
759Sjkh};
769Sjkh
7711927Speter/* Expand all keywords by default */
7811927Speterstatic int ExpandKeyword[] = {
7911927Speter	false,
8011927Speter	true, true, true, true,
8125699Speter	true, true, true, true, true, true, true, true,
8225699Speter	true
8311927Speter};
8425699Speterenum markers LocalIdMode = Id;
859Sjkh
869Sjkh	enum markers
879Sjkhtrymatch(string)
889Sjkh	char const *string;
899Sjkh/* function: Checks whether string starts with a keyword followed
909Sjkh * by a KDELIM or a VDELIM.
919Sjkh * If successful, returns the appropriate marker, otherwise Nomatch.
929Sjkh */
939Sjkh{
949Sjkh        register int j;
959Sjkh	register char const *p, *s;
969Sjkh	for (j = sizeof(Keyword)/sizeof(*Keyword);  (--j);  ) {
9711927Speter		if (!ExpandKeyword[j])
9811927Speter			continue;
999Sjkh		/* try next keyword */
1009Sjkh		p = Keyword[j];
10125699Speter		if (p == NULL)
10225699Speter			continue;
1039Sjkh		s = string;
1049Sjkh		while (*p++ == *s++) {
1059Sjkh			if (!*p)
1069Sjkh			    switch (*s) {
1079Sjkh				case KDELIM:
1089Sjkh				case VDELIM:
1099Sjkh				    return (enum markers)j;
1109Sjkh				default:
1119Sjkh				    return Nomatch;
1129Sjkh			    }
1139Sjkh		}
1149Sjkh        }
1159Sjkh        return(Nomatch);
1169Sjkh}
1179Sjkh
11825699Speter	void
11911927SpetersetIncExc(arg)
12025699Speter	char const *arg;
12111927Speter/* Sets up the ExpandKeyword table according to command-line flags */
12211927Speter{
12311927Speter	char *key;
12425699Speter	char *copy, *next;
12511927Speter	int include = 0, j;
12611927Speter
12725699Speter	copy = strdup(arg);
12825699Speter	next = copy;
12925699Speter	switch (*next++) {
13011927Speter	    case 'e':
13111927Speter		include = false;
13211927Speter		break;
13311927Speter	    case 'i':
13411927Speter		include = true;
13511927Speter		break;
13611927Speter	    default:
13725699Speter		free(copy);
13825699Speter		return;
13911927Speter	}
14011927Speter	if (include)
14111927Speter		for (j = sizeof(Keyword)/sizeof(*Keyword);  (--j);  )
14211927Speter			ExpandKeyword[j] = false;
14325699Speter	key = strtok(next, ",");
14411927Speter	while (key) {
14525699Speter		for (j = sizeof(Keyword)/sizeof(*Keyword);  (--j);  ) {
14625699Speter			if (Keyword[j] == NULL)
14725699Speter				continue;
14811927Speter			if (!strcmp(key, Keyword[j]))
14911927Speter				ExpandKeyword[j] = include;
15025699Speter		}
15111927Speter		key = strtok(NULL, ",");
15211927Speter	}
15325699Speter	free(copy);
15425699Speter	return;
15511927Speter}
15625699Speter
15725699Speter	void
15825699SpetersetRCSLocalId(string)
15925699Speter	char const *string;
16025699Speter/* function: sets local RCS id and RCSLOCALID envariable */
16125699Speter{
16225699Speter	static char local_id[keylength+1];
16325699Speter	char *copy, *next, *key;
16425699Speter	int j;
16525699Speter
16625699Speter	copy = strdup(string);
16725699Speter	next = copy;
16825699Speter	key = strtok(next, "=");
16925699Speter	if (strlen(key) > keylength)
17090399Sru		faterror("LocalId is too long");
17125699Speter	VOID strcpy(local_id, key);
17225699Speter	Keyword[LocalId] = local_id;
17325699Speter
17425699Speter	/* options? */
17525699Speter	while (key = strtok(NULL, ",")) {
17625699Speter		if (!strcmp(key, Keyword[Id]))
17725699Speter			LocalIdMode=Id;
17825699Speter		else if (!strcmp(key, Keyword[Header]))
17925699Speter			LocalIdMode=Header;
18025699Speter		else if (!strcmp(key, Keyword[CVSHeader]))
18125699Speter			LocalIdMode=CVSHeader;
18225699Speter		else
18325699Speter			error("Unknown LocalId mode");
18425699Speter	}
18525699Speter	free(copy);
18625699Speter}
187