Removed obsolete lexer/parser files
This commit is contained in:
parent
fdf7e4ea8b
commit
44d91bdf6b
316
src/grammar.y
316
src/grammar.y
@ -1,316 +0,0 @@
|
|||||||
/* $Id: grammar.y,v 1.25 2004-04-27 18:53:14 rjkaes Exp $
|
|
||||||
*
|
|
||||||
* This is the grammar for tinyproxy's configuration file. It needs to be
|
|
||||||
* in sync with scanner.l. If you know more about yacc and lex than I do
|
|
||||||
* please update these files.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000 Robert James Kaes (rjkaes@flarenet.com)
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the
|
|
||||||
* Free Software Foundation; either version 2, or (at your option) any
|
|
||||||
* later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
%{
|
|
||||||
|
|
||||||
#include "tinyproxy.h"
|
|
||||||
|
|
||||||
#include "acl.h"
|
|
||||||
#include "anonymous.h"
|
|
||||||
#include "child.h"
|
|
||||||
#include "filter.h"
|
|
||||||
#include "htmlerror.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "reqs.h"
|
|
||||||
|
|
||||||
void yyerror(char *s);
|
|
||||||
int yylex(void);
|
|
||||||
|
|
||||||
%}
|
|
||||||
|
|
||||||
%union {
|
|
||||||
unsigned int num;
|
|
||||||
char *cptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* statements */
|
|
||||||
%token KW_PORT KW_LISTEN
|
|
||||||
%token KW_LOGFILE KW_PIDFILE KW_SYSLOG
|
|
||||||
%token KW_MAXCLIENTS KW_MAXSPARESERVERS KW_MINSPARESERVERS KW_STARTSERVERS
|
|
||||||
%token KW_MAXREQUESTSPERCHILD
|
|
||||||
%token KW_TIMEOUT
|
|
||||||
%token KW_USER KW_GROUP
|
|
||||||
%token KW_ANONYMOUS KW_XTINYPROXY
|
|
||||||
%token KW_FILTER KW_FILTERURLS KW_FILTEREXTENDED KW_FILTER_DEFAULT_DENY
|
|
||||||
%token KW_FILTER_CASESENSITIVE
|
|
||||||
%token KW_UPSTREAM
|
|
||||||
%token KW_REVERSEPATH KW_REVERSEONLY KW_REVERSEMAGIC KW_REVERSEBASEURL
|
|
||||||
%token KW_CONNECTPORT KW_BIND KW_BINDSAME
|
|
||||||
%token KW_STATHOST
|
|
||||||
%token KW_ALLOW KW_DENY
|
|
||||||
%token KW_ERRORPAGE KW_DEFAULT_ERRORPAGE
|
|
||||||
%token KW_STATPAGE
|
|
||||||
%token KW_VIA_PROXY_NAME
|
|
||||||
|
|
||||||
/* yes/no switches */
|
|
||||||
%token KW_YES KW_NO
|
|
||||||
|
|
||||||
/* settings for loglevel */
|
|
||||||
%token KW_LOGLEVEL
|
|
||||||
%token KW_LOG_CRITICAL KW_LOG_ERROR KW_LOG_WARNING KW_LOG_NOTICE KW_LOG_CONNECT KW_LOG_INFO
|
|
||||||
|
|
||||||
%token <cptr> IDENTIFIER
|
|
||||||
%token <num> NUMBER
|
|
||||||
%token <cptr> STRING
|
|
||||||
%token <cptr> NUMERIC_ADDRESS
|
|
||||||
%token <cptr> NETMASK_ADDRESS
|
|
||||||
|
|
||||||
%type <num> yesno
|
|
||||||
%type <cptr> string
|
|
||||||
%type <cptr> network_address
|
|
||||||
%type <cptr> unique_address
|
|
||||||
%type <num> loglevels
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
start
|
|
||||||
: /* empty */
|
|
||||||
| start line
|
|
||||||
;
|
|
||||||
|
|
||||||
line
|
|
||||||
: '\n'
|
|
||||||
| statement '\n'
|
|
||||||
;
|
|
||||||
|
|
||||||
statement
|
|
||||||
: KW_PORT NUMBER { config.port = $2; }
|
|
||||||
| KW_TIMEOUT NUMBER { config.idletimeout = $2; }
|
|
||||||
| KW_SYSLOG yesno
|
|
||||||
{
|
|
||||||
#ifdef HAVE_SYSLOG_H
|
|
||||||
config.syslog = $2;
|
|
||||||
#else
|
|
||||||
log_message(LOG_WARNING, "Syslog support was not compiled in.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
| KW_MAXCLIENTS NUMBER { child_configure(CHILD_MAXCLIENTS, $2); }
|
|
||||||
| KW_MAXSPARESERVERS NUMBER { child_configure(CHILD_MAXSPARESERVERS, $2); }
|
|
||||||
| KW_MINSPARESERVERS NUMBER { child_configure(CHILD_MINSPARESERVERS, $2); }
|
|
||||||
| KW_STARTSERVERS NUMBER { child_configure(CHILD_STARTSERVERS, $2); }
|
|
||||||
| KW_MAXREQUESTSPERCHILD NUMBER { child_configure(CHILD_MAXREQUESTSPERCHILD, $2); }
|
|
||||||
| KW_LOGFILE string
|
|
||||||
{
|
|
||||||
config.logf_name = $2;
|
|
||||||
if (!config.logf_name) {
|
|
||||||
fprintf(stderr, "bad log file\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
| KW_PIDFILE string { config.pidpath = $2; }
|
|
||||||
| KW_USER string { config.username = $2; }
|
|
||||||
| KW_GROUP string { config.group = $2; }
|
|
||||||
| KW_ANONYMOUS string { anonymous_insert($2); }
|
|
||||||
| KW_ERRORPAGE NUMBER string { add_new_errorpage($3, $2); }
|
|
||||||
| KW_DEFAULT_ERRORPAGE string { config.errorpage_undef = $2; }
|
|
||||||
| KW_STATPAGE string { config.statpage = $2; }
|
|
||||||
| KW_FILTER string
|
|
||||||
{
|
|
||||||
#ifdef FILTER_ENABLE
|
|
||||||
config.filter = $2;
|
|
||||||
#else
|
|
||||||
log_message(LOG_WARNING, "Filter support was not compiled in.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
| KW_FILTERURLS yesno
|
|
||||||
{
|
|
||||||
#ifdef FILTER_ENABLE
|
|
||||||
config.filter_url = $2;
|
|
||||||
#else
|
|
||||||
log_message(LOG_WARNING, "Filter support wss not compiled in.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
| KW_FILTEREXTENDED yesno
|
|
||||||
{
|
|
||||||
#ifdef FILTER_ENABLE
|
|
||||||
config.filter_extended = $2;
|
|
||||||
#else
|
|
||||||
log_message(LOG_WARNING, "Filter support was not compiled in.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
| KW_FILTER_CASESENSITIVE yesno
|
|
||||||
{
|
|
||||||
#ifdef FILTER_ENABLE
|
|
||||||
config.filter_casesensitive = $2;
|
|
||||||
#else
|
|
||||||
log_message(LOG_WARNING, "Filter support was not compiled in.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
| KW_FILTER_DEFAULT_DENY yesno
|
|
||||||
{
|
|
||||||
#ifdef FILTER_ENABLE
|
|
||||||
if ($2)
|
|
||||||
filter_set_default_policy(FILTER_DEFAULT_DENY);
|
|
||||||
#else
|
|
||||||
log_message(LOG_WARNING, "FIlter support was not compiled in.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
| KW_XTINYPROXY network_address
|
|
||||||
{
|
|
||||||
#ifdef XTINYPROXY_ENABLE
|
|
||||||
config.my_domain = $2;
|
|
||||||
#else
|
|
||||||
log_message(LOG_WARNING, "X-Tinyproxy header support was not compiled in.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
| KW_REVERSEPATH string
|
|
||||||
{
|
|
||||||
#ifdef REVERSE_SUPPORT
|
|
||||||
reversepath_add(NULL, $2);
|
|
||||||
#else
|
|
||||||
log_message(LOG_WARNING, "Reverse proxy support was not compiled in.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
| KW_REVERSEPATH string string
|
|
||||||
{
|
|
||||||
#ifdef REVERSE_SUPPORT
|
|
||||||
reversepath_add($2, $3);
|
|
||||||
#else
|
|
||||||
log_message(LOG_WARNING, "Reverse proxy support was not compiled in.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
| KW_REVERSEONLY yesno
|
|
||||||
{
|
|
||||||
#ifdef REVERSE_SUPPORT
|
|
||||||
config.reverseonly = $2;
|
|
||||||
#else
|
|
||||||
log_message(LOG_WARNING, "Reverse proxy support was not compiled in.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
| KW_REVERSEMAGIC yesno
|
|
||||||
{
|
|
||||||
#ifdef REVERSE_SUPPORT
|
|
||||||
config.reversemagic = $2;
|
|
||||||
#else
|
|
||||||
log_message(LOG_WARNING, "Reverse proxy support was not compiled in.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
| KW_REVERSEBASEURL string
|
|
||||||
{
|
|
||||||
#ifdef REVERSE_SUPPORT
|
|
||||||
config.reversebaseurl = $2;
|
|
||||||
#else
|
|
||||||
log_message(LOG_WARNING, "Reverse proxy support was not compiled in.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
| KW_UPSTREAM unique_address ':' NUMBER
|
|
||||||
{
|
|
||||||
#ifdef UPSTREAM_SUPPORT
|
|
||||||
upstream_add($2, $4, NULL);
|
|
||||||
#else
|
|
||||||
log_message(LOG_WARNING, "Upstream proxy support was not compiled in.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
| KW_UPSTREAM unique_address ':' NUMBER STRING
|
|
||||||
{
|
|
||||||
#ifdef UPSTREAM_SUPPORT
|
|
||||||
upstream_add($2, $4, $5);
|
|
||||||
#else
|
|
||||||
log_message(LOG_WARNING, "Upstream proxy support was not compiled in.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
| KW_NO KW_UPSTREAM STRING
|
|
||||||
{
|
|
||||||
#ifdef UPSTREAM_SUPPORT
|
|
||||||
upstream_add(NULL, 0, $3);
|
|
||||||
#else
|
|
||||||
log_message(LOG_WARNING, "Upstream proxy support was not compiled in.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
| KW_LISTEN NUMERIC_ADDRESS
|
|
||||||
{
|
|
||||||
log_message(LOG_INFO, "Establishing listening socket on IP %s", $2);
|
|
||||||
config.ipAddr = $2;
|
|
||||||
}
|
|
||||||
| KW_ALLOW network_address { insert_acl($2, ACL_ALLOW); }
|
|
||||||
| KW_DENY network_address { insert_acl($2, ACL_DENY); }
|
|
||||||
| KW_LOGLEVEL loglevels { set_log_level($2); }
|
|
||||||
| KW_CONNECTPORT NUMBER { add_connect_port_allowed($2); }
|
|
||||||
| KW_BIND NUMERIC_ADDRESS
|
|
||||||
{
|
|
||||||
#ifndef TRANSPARENT_PROXY
|
|
||||||
log_message(LOG_INFO, "Binding outgoing connections to %s", $2);
|
|
||||||
config.bind_address = $2;
|
|
||||||
#else
|
|
||||||
log_message(LOG_WARNING, "The 'Bind' directive can not be used with transparent proxy support. Ignoring the directive.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
| KW_BINDSAME yesno
|
|
||||||
{
|
|
||||||
log_message(LOG_INFO, "Binding outgoing connections to incoming IP");
|
|
||||||
config.bindsame = $2;
|
|
||||||
}
|
|
||||||
| KW_VIA_PROXY_NAME string
|
|
||||||
{
|
|
||||||
log_message(LOG_INFO, "Setting \"Via\" proxy name to: %s", $2);
|
|
||||||
config.via_proxy_name = $2;
|
|
||||||
}
|
|
||||||
| KW_STATHOST string
|
|
||||||
{
|
|
||||||
log_message(LOG_INFO, "Stathost is set to \"%s\"", $2);
|
|
||||||
config.stathost = $2;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
loglevels
|
|
||||||
: KW_LOG_CRITICAL { $$ = LOG_CRIT; }
|
|
||||||
| KW_LOG_ERROR { $$ = LOG_ERR; }
|
|
||||||
| KW_LOG_WARNING { $$ = LOG_WARNING; }
|
|
||||||
| KW_LOG_NOTICE { $$ = LOG_NOTICE; }
|
|
||||||
| KW_LOG_CONNECT { $$ = LOG_CONN; }
|
|
||||||
| KW_LOG_INFO { $$ = LOG_INFO; }
|
|
||||||
;
|
|
||||||
|
|
||||||
network_address
|
|
||||||
: unique_address
|
|
||||||
| NETMASK_ADDRESS
|
|
||||||
;
|
|
||||||
|
|
||||||
unique_address
|
|
||||||
: IDENTIFIER
|
|
||||||
| NUMERIC_ADDRESS
|
|
||||||
;
|
|
||||||
|
|
||||||
yesno
|
|
||||||
: KW_YES { $$ = 1; }
|
|
||||||
| KW_NO { $$ = 0; }
|
|
||||||
| NUMBER { $$ = $1; }
|
|
||||||
;
|
|
||||||
|
|
||||||
string
|
|
||||||
: IDENTIFIER
|
|
||||||
| STRING
|
|
||||||
;
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
extern int yylineno;
|
|
||||||
|
|
||||||
void
|
|
||||||
yyerror(char *s)
|
|
||||||
{
|
|
||||||
static int headerdisplayed = 0;
|
|
||||||
|
|
||||||
if (!headerdisplayed) {
|
|
||||||
fprintf(stderr, "Errors in configuration file:\n");
|
|
||||||
headerdisplayed = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "\t%s:%d: %s\n", config.config_file, yylineno, s);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
173
src/scanner.l
173
src/scanner.l
@ -1,173 +0,0 @@
|
|||||||
/* $Id: scanner.l,v 1.24 2004-04-27 18:53:14 rjkaes Exp $
|
|
||||||
*
|
|
||||||
* This builds the scanner for the tinyproxy configuration file. This
|
|
||||||
* file needs to stay in sync with grammar.y. If someone knows lex and yacc
|
|
||||||
* better than I do, please update these files.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000 Robert James Kaes (rjkaes@flarenet.com)
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the
|
|
||||||
* Free Software Foundation; either version 2, or (at your option) any
|
|
||||||
* later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*/
|
|
||||||
%{
|
|
||||||
|
|
||||||
#include "tinyproxy.h"
|
|
||||||
|
|
||||||
#include "grammar.h"
|
|
||||||
|
|
||||||
struct keyword {
|
|
||||||
char *kw_name;
|
|
||||||
int kw_token;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct keyword keywords[] = {
|
|
||||||
/* statements */
|
|
||||||
{ "port", KW_PORT },
|
|
||||||
{ "logfile", KW_LOGFILE },
|
|
||||||
{ "syslog", KW_SYSLOG },
|
|
||||||
{ "maxclients", KW_MAXCLIENTS },
|
|
||||||
{ "maxspareservers", KW_MAXSPARESERVERS },
|
|
||||||
{ "minspareservers", KW_MINSPARESERVERS },
|
|
||||||
{ "startservers", KW_STARTSERVERS },
|
|
||||||
{ "maxrequestsperchild", KW_MAXREQUESTSPERCHILD },
|
|
||||||
{ "pidfile", KW_PIDFILE },
|
|
||||||
{ "timeout", KW_TIMEOUT },
|
|
||||||
{ "listen", KW_LISTEN },
|
|
||||||
{ "user", KW_USER },
|
|
||||||
{ "group", KW_GROUP },
|
|
||||||
{ "anonymous", KW_ANONYMOUS },
|
|
||||||
{ "filter", KW_FILTER },
|
|
||||||
{ "filterurls", KW_FILTERURLS },
|
|
||||||
{ "filterextended", KW_FILTEREXTENDED },
|
|
||||||
{ "filterdefaultdeny", KW_FILTER_DEFAULT_DENY },
|
|
||||||
{ "filtercasesensitive", KW_FILTER_CASESENSITIVE },
|
|
||||||
{ "xtinyproxy", KW_XTINYPROXY },
|
|
||||||
{ "reversepath", KW_REVERSEPATH },
|
|
||||||
{ "reverseonly", KW_REVERSEONLY },
|
|
||||||
{ "reversemagic", KW_REVERSEMAGIC },
|
|
||||||
{ "reversebaseurl", KW_REVERSEBASEURL },
|
|
||||||
{ "upstream", KW_UPSTREAM },
|
|
||||||
{ "allow", KW_ALLOW },
|
|
||||||
{ "deny", KW_DENY },
|
|
||||||
{ "connectport", KW_CONNECTPORT },
|
|
||||||
{ "bind", KW_BIND },
|
|
||||||
{ "bindsame", KW_BINDSAME },
|
|
||||||
{ "viaproxyname", KW_VIA_PROXY_NAME },
|
|
||||||
{ "stathost", KW_STATHOST },
|
|
||||||
{ "errorfile", KW_ERRORPAGE },
|
|
||||||
{ "defaulterrorfile", KW_DEFAULT_ERRORPAGE },
|
|
||||||
{ "statfile", KW_STATPAGE },
|
|
||||||
|
|
||||||
/* loglevel and the settings */
|
|
||||||
{ "loglevel", KW_LOGLEVEL },
|
|
||||||
{ "critical", KW_LOG_CRITICAL },
|
|
||||||
{ "error", KW_LOG_ERROR },
|
|
||||||
{ "warning", KW_LOG_WARNING },
|
|
||||||
{ "notice", KW_LOG_NOTICE },
|
|
||||||
{ "connect", KW_LOG_CONNECT },
|
|
||||||
{ "info", KW_LOG_INFO },
|
|
||||||
|
|
||||||
/* on/off switches */
|
|
||||||
{ "yes", KW_YES },
|
|
||||||
{ "on", KW_YES },
|
|
||||||
{ "no", KW_NO },
|
|
||||||
{ "off", KW_NO }
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#define YY_NO_UNPUT 1
|
|
||||||
|
|
||||||
#define MAX_REGEXP_LEN 1024
|
|
||||||
|
|
||||||
char tiny_buf[MAX_REGEXP_LEN];
|
|
||||||
char *tiny_str;
|
|
||||||
|
|
||||||
static int check_reserved_words(char *token);
|
|
||||||
static void append_string(int length, char *str);
|
|
||||||
static void append_char(char c);
|
|
||||||
|
|
||||||
%}
|
|
||||||
|
|
||||||
%option noyywrap batch yylineno
|
|
||||||
|
|
||||||
white [ \t]
|
|
||||||
digit [0-9]
|
|
||||||
alpha [a-zA-Z]
|
|
||||||
alphanum [a-zA-Z0-9]
|
|
||||||
word [^ \#'"\(\)\{\}\\;\n\t,|\.]
|
|
||||||
|
|
||||||
%x string
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
\#.*$ ;
|
|
||||||
\n { return '\n'; }
|
|
||||||
":" { return ':'; }
|
|
||||||
{white}+ ;
|
|
||||||
0x{digit}+ { yylval.num = strtol(yytext, NULL, 16); return NUMBER; }
|
|
||||||
0{digit}+ { yylval.num = strtol(yytext, NULL, 8); return NUMBER; }
|
|
||||||
{digit}+ { yylval.num = atoi(yytext); return NUMBER; }
|
|
||||||
{alpha}({alphanum}|[-._])+ { return check_reserved_words(yytext); }
|
|
||||||
|
|
||||||
\" {
|
|
||||||
tiny_str = tiny_buf;
|
|
||||||
BEGIN(string);
|
|
||||||
}
|
|
||||||
<string>\\a { append_char(7); }
|
|
||||||
<string>\\n { append_char(10); }
|
|
||||||
<string>\\r { append_char(13); }
|
|
||||||
<string>\\t { append_char(9); }
|
|
||||||
<string>\\v { append_char(11); }
|
|
||||||
<string>\\[^anrtv] { append_string(1, yytext + 1); }
|
|
||||||
<string>\" {
|
|
||||||
BEGIN(INITIAL);
|
|
||||||
yylval.cptr = strdup(tiny_buf);
|
|
||||||
return STRING;
|
|
||||||
}
|
|
||||||
<string>[^"\\]+ { append_string(strlen(yytext), yytext); }
|
|
||||||
|
|
||||||
|
|
||||||
({digit}{1,3}\.){3}{digit}{1,3} { yylval.cptr = strdup(yytext); return NUMERIC_ADDRESS; }
|
|
||||||
({digit}{1,3}\.){3}{digit}{1,3}\/{digit}+ { yylval.cptr = strdup(yytext); return NETMASK_ADDRESS; }
|
|
||||||
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
int
|
|
||||||
check_reserved_words(char *token)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < (sizeof(keywords) / sizeof(struct keyword)); i++) {
|
|
||||||
if (strcasecmp(keywords[i].kw_name, token) == 0) {
|
|
||||||
return keywords[i].kw_token;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
yylval.cptr = strdup(token);
|
|
||||||
return IDENTIFIER;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
append_string(int length, char *s)
|
|
||||||
{
|
|
||||||
int to_copy = min(MAX_REGEXP_LEN - (tiny_str - tiny_buf) - 1, length);
|
|
||||||
|
|
||||||
memcpy(tiny_str, s, to_copy);
|
|
||||||
tiny_str += to_copy;
|
|
||||||
*tiny_str = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
append_char(char c)
|
|
||||||
{
|
|
||||||
*tiny_str = c;
|
|
||||||
tiny_str++;
|
|
||||||
*tiny_str = 0;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user