src/lib/libkeynote/keynote-ver.l

272 lines
5.5 KiB
Plaintext

%{
/* $OpenBSD: keynote-ver.l,v 1.20 2017/08/28 17:07:19 millert Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@dsl.cis.upenn.edu)
*
* This code was written by Angelos D. Keromytis in Philadelphia, PA, USA,
* in April-May 1998
*
* Copyright (C) 1998, 1999 by Angelos D. Keromytis.
*
* Permission to use, copy, and modify this software with or without fee
* is hereby granted, provided that this entire notice is included in
* all copies of any software which is or includes a copy or
* modification of this software.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, THE AUTHORS MAKES NO
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*/
#include <sys/time.h>
#include <sys/types.h>
#include <ctype.h>
#include <regex.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "z.tab.h"
#include "header.h"
#include "keynote.h"
static void mystrncpy(char *, char *, int);
%}
vstring [a-zA-Z0-9][a-zA-Z0-9_]*
litstring \"(((\\\n)|(\\.)|(\\\\)|([^\\\n\"]))*)\"
comment "#"[^\n]*
%s FIRSTPART MIDDLEPART SECONDPART KEYSTATE
%pointer
%option noinput noyywrap yylineno never-interactive
%%
<MIDDLEPART>"=" {
BEGIN(SECONDPART);
return EQ;
}
<FIRSTPART>{vstring} {
int len = strlen(kvtext) + 1;
kvlval.s.string = calloc(len, sizeof(char));
if (kvlval.s.string == NULL) {
keynote_errno = ERROR_MEMORY;
return -1;
}
strlcpy(kvlval.s.string, kvtext, len);
BEGIN(MIDDLEPART);
return VSTRING;
}
<KEYSTATE,SECONDPART>{litstring} { kvlval.s.string = calloc(strlen(kvtext) - 1,
sizeof(char));
if (kvlval.s.string == NULL) {
keynote_errno = ERROR_MEMORY;
return -1;
}
mystrncpy(kvlval.s.string, kvtext + 1,
strlen(kvtext) - 2);
BEGIN(FIRSTPART);
return STRING;
}
<FIRSTPART,KEYSTATE>{comment} ;
[ \t\n] ;
. { keynote_errno = ERROR_SYNTAX; return -1; REJECT; }
%%
/*
* Return RESULT_TRUE if character is octal digit, RESULT_FALSE otherwise.
*/
static int
is_octal(char c)
{
switch (c)
{
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
return RESULT_TRUE;
default:
return RESULT_FALSE;
}
}
/*
* Return octal value (non-zero) if argument starts with such a
* representation, otherwise 0.
*/
static unsigned char
get_octal(char *s, int len, int *adv)
{
unsigned char res = 0;
if (*s == '0')
{
if (len > 0)
{
if (is_octal(*(s + 1)))
{
res = *(s + 1) - '0';
*adv = 2;
if (is_octal(*(s + 2)) && (len - 1 > 0))
{
res = res * 8 + (*(s + 2) - '0');
*adv = 3;
}
}
}
}
else
if (is_octal(*s) && (len - 1 > 0)) /* Non-zero leading */
{
if (is_octal(*(s + 1)) &&
is_octal(*(s + 2)))
{
*adv = 3;
res = (((*s) - '0') * 64) +
(((*(s + 1)) - '0') * 8) +
((*(s + 2)) - '0');
}
}
return res;
}
/*
* Copy at most len characters to string s1 from string s2, taking
* care of escaped characters in the process. String s1 is assumed
* to have enough space, and be zero'ed.
*/
void
mystrncpy(char *s1, char *s2, int len)
{
unsigned char c;
int advance;
if (len == 0)
return;
while (len-- > 0)
{
if (*s2 == '\\')
{
s2++;
if (len-- <= 0)
break;
if (*s2 == '\n')
{
while (isspace((unsigned char)*(++s2)) && (len-- > 0))
;
}
else
if ((c = get_octal(s2, len, &advance)) != 0)
{
len -= advance - 1;
s2 += advance;
*s1++ = c;
}
else
if (*s2 == 'n') /* Newline */
{
*s1++ = '\n';
s2++;
}
else
if (*s2 == 't') /* Tab */
{
*s1++ = '\t';
s2++;
}
else
if (*s2 == 'r') /* Linefeed */
{
*s1++ = '\r';
s2++;
}
else
if (*s2 == 'f') /* Formfeed */
{
*s1++ = '\f';
s2++;
}
else
if ((*s1++ = *s2++) == 0)
break;
continue;
}
if ((*s1++ = *s2++) == 0)
break;
}
}
/*
* Parse a file that contains environment variable/value pairs.
* Return -1 on failure.
*/
int
read_environment(char *filename)
{
YY_BUFFER_STATE kvfoo;
FILE *fp;
int i;
if ((fp = fopen(filename, "r")) == NULL) {
perror(filename);
return -1;
}
kvfoo = kv_create_buffer(fp, YY_BUF_SIZE);
kv_switch_to_buffer(kvfoo);
BEGIN(FIRSTPART);
i = kvparse();
kv_delete_buffer(kvfoo);
fclose(fp);
switch (i)
{
case 0:
return 0;
default:
if (keynote_errno == ERROR_MEMORY)
fprintf(stderr,
"Memory error while processing environment file <%s>\n",
filename);
else
fprintf(stderr,
"Syntax error in environment file <%s>, line %d\n",
filename, kvlineno);
return -1;
}
/* Used to avoid compiler (-Wall) warnings. Never reached */
if (0)
{
yyunput(0, NULL);
}
}
/*
* Parse a key.
*/
void
parse_key(char *buf)
{
YY_BUFFER_STATE key_state;
int err;
key_state = kv_scan_string(buf);
BEGIN(KEYSTATE);
err = kvparse();
kv_delete_buffer(key_state);
if (err != 0)
if (keynote_errno == 0)
keynote_errno = ERROR_SYNTAX;
}