*** empty log message ***
This commit is contained in:
parent
4964a434e8
commit
cac8f41ec1
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: StdAwk.java,v 1.3 2006-11-24 15:37:05 bacon Exp $
|
||||
* $Id: StdAwk.java,v 1.4 2006-11-25 15:51:29 bacon Exp $
|
||||
*/
|
||||
|
||||
package ase.awk;
|
||||
@ -8,28 +8,41 @@ import java.io.*;
|
||||
|
||||
public abstract class StdAwk extends Awk
|
||||
{
|
||||
private FileReader insrc;
|
||||
private InputStreamReader src_in = null;
|
||||
private OutputStreamWriter src_out = null;
|
||||
|
||||
private String[] cin;
|
||||
private int cin_no;
|
||||
private String[] cout;
|
||||
private int cout_no;
|
||||
private String[] sin = null;
|
||||
private int sin_no = 0;
|
||||
private String sout = null;
|
||||
|
||||
private String[] cin = null;
|
||||
private int cin_no = 0;
|
||||
private String[] cout = null;
|
||||
private int cout_no = 0;
|
||||
|
||||
public StdAwk () throws Exception
|
||||
{
|
||||
super ();
|
||||
}
|
||||
|
||||
insrc = null;
|
||||
/* ===== overridden major methods ===== */
|
||||
public void parse () throws Exception
|
||||
{
|
||||
sin = getSourceNames (); sin_no = 0;
|
||||
sout = getDeparsedSourceName ();
|
||||
super.parse ();
|
||||
}
|
||||
|
||||
cin = getInputConsoleNames ();
|
||||
cout = getOutputConsoleNames ();
|
||||
cin_no = 0;
|
||||
cout_no = 0;
|
||||
public void run () throws Exception
|
||||
{
|
||||
cin = getInputConsoleNames (); cin_no = 0;
|
||||
cout = getOutputConsoleNames (); cout_no = 0;
|
||||
super.run ();
|
||||
}
|
||||
|
||||
/* ===== source code names ===== */
|
||||
protected abstract String[] getSourceNames ();
|
||||
protected String getDeparseName () { return null; }
|
||||
protected String getDeparsedSourceName () { return null; }
|
||||
|
||||
/* ===== console names ===== */
|
||||
protected abstract String[] getInputConsoleNames ();
|
||||
@ -40,17 +53,24 @@ public abstract class StdAwk extends Awk
|
||||
{
|
||||
if (mode == SOURCE_READ)
|
||||
{
|
||||
try { insrc = new FileReader ("t.awk"); }
|
||||
catch (IOException e) { return -1; }
|
||||
InputStreamReader isr;
|
||||
sin_no = 0;
|
||||
|
||||
if (sin_no >= sin.length) return 0;
|
||||
isr = get_input_stream (sin[sin_no]);
|
||||
if (isr == null) return -1;
|
||||
|
||||
src_in = isr;
|
||||
sin_no++;
|
||||
return 1;
|
||||
}
|
||||
else if (mode == SOURCE_WRITE)
|
||||
{
|
||||
/*
|
||||
try { outsrc = new FileWriter ("t.out"); }
|
||||
catch (IOException e) { return -1; }
|
||||
return 1;
|
||||
*/
|
||||
OutputStreamWriter osw;
|
||||
if (sout == null) return 1;
|
||||
osw = get_output_stream (sout);
|
||||
if (osw == null) return -1;
|
||||
src_out = osw;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -61,18 +81,16 @@ public abstract class StdAwk extends Awk
|
||||
{
|
||||
if (mode == SOURCE_READ)
|
||||
{
|
||||
try { insrc.close (); }
|
||||
try { src_in.close (); }
|
||||
catch (IOException e) { return -1; }
|
||||
return 0;
|
||||
}
|
||||
else if (mode == SOURCE_WRITE)
|
||||
{
|
||||
/*
|
||||
try { outsrc.close (); }
|
||||
if (src_out == null) return 0;
|
||||
try { src_out.close (); }
|
||||
catch (IOException e) { return -1; }
|
||||
return 0;
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
@ -80,18 +98,42 @@ public abstract class StdAwk extends Awk
|
||||
|
||||
protected int read_source (char[] buf, int len)
|
||||
{
|
||||
try { return insrc.read (buf, 0, len); }
|
||||
catch (IOException e) { return -1; }
|
||||
int n;
|
||||
|
||||
try {
|
||||
n = src_in.read (buf, 0, len);
|
||||
while (n == -1)
|
||||
{
|
||||
InputStreamReader isr;
|
||||
if (sin_no >= sin.length) return 0;
|
||||
|
||||
isr = get_input_stream (sin[sin_no]);
|
||||
if (isr == null) return -1;
|
||||
|
||||
try { src_in.close (); }
|
||||
catch (IOException ec) { /* ignore */ }
|
||||
|
||||
src_in = isr;
|
||||
sin_no++;
|
||||
|
||||
n = src_in.read (buf, 0, len);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
protected int write_source (char[] buf, int len)
|
||||
{
|
||||
/*
|
||||
try { outsrc.write (buf, 0, len); }
|
||||
//System.out.println (new String(buf, 0, len));
|
||||
if (src_out == null) return len;
|
||||
try { src_out.write (buf, 0, len); }
|
||||
catch (IOException e) { return -1; }
|
||||
return len;
|
||||
*/
|
||||
return len;
|
||||
}
|
||||
|
||||
/* ===== console ===== */
|
||||
@ -104,6 +146,8 @@ public abstract class StdAwk extends Awk
|
||||
if (mode == Extio.MODE_CONSOLE_READ)
|
||||
{
|
||||
InputStreamReader isr;
|
||||
cin_no = 0;
|
||||
|
||||
if (cin_no >= cin.length) return 0;
|
||||
isr = get_input_stream (cin[cin_no]);
|
||||
if (isr == null) return -1;
|
||||
@ -117,6 +161,7 @@ public abstract class StdAwk extends Awk
|
||||
else if (mode == Extio.MODE_CONSOLE_WRITE)
|
||||
{
|
||||
OutputStreamWriter osw;
|
||||
cout_no = 0;
|
||||
|
||||
if (cout_no >= cout.length) return 0;
|
||||
osw = get_output_stream (cout[cout_no]);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: awk.c,v 1.90 2006-10-31 14:31:46 bacon Exp $
|
||||
* $Id: awk.c,v 1.91 2006-11-25 15:51:30 bacon Exp $
|
||||
*/
|
||||
|
||||
#if defined(__BORLANDC__)
|
||||
@ -132,8 +132,12 @@ ase_awk_t* ase_awk_open (const ase_awk_syscas_t* syscas)
|
||||
awk->bfn.sys = ASE_NULL;
|
||||
awk->bfn.user = ASE_NULL;
|
||||
|
||||
awk->parse.depth.loop = 0;
|
||||
awk->parse.depth.expr = 0;
|
||||
awk->parse.depth.cur.block = 0;
|
||||
awk->parse.depth.cur.loop = 0;
|
||||
awk->parse.depth.cur.expr = 0;
|
||||
|
||||
ase_awk_setmaxparsedepth (awk, ASE_AWK_DEPTH_BLOCK, 0);
|
||||
ase_awk_setmaxparsedepth (awk, ASE_AWK_DEPTH_EXPR, 0);
|
||||
|
||||
awk->run.count = 0;
|
||||
awk->run.ptr = ASE_NULL;
|
||||
@ -187,8 +191,9 @@ int ase_awk_clear (ase_awk_t* awk)
|
||||
ase_awk_tab_clear (&awk->parse.params);
|
||||
|
||||
awk->parse.nlocals_max = 0;
|
||||
awk->parse.depth.expr = 0;
|
||||
awk->parse.depth.loop = 0;
|
||||
awk->parse.depth.cur.block = 0;
|
||||
awk->parse.depth.cur.loop = 0;
|
||||
awk->parse.depth.cur.expr = 0;
|
||||
|
||||
/* clear parse trees */
|
||||
awk->tree.nbglobals = 0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: awk.h,v 1.151 2006-11-24 13:20:48 bacon Exp $
|
||||
* $Id: awk.h,v 1.152 2006-11-25 15:51:30 bacon Exp $
|
||||
*/
|
||||
|
||||
#ifndef _ASE_AWK_AWK_H_
|
||||
@ -307,6 +307,12 @@ enum
|
||||
ASE_AWK_EREXGARBAGE /* garbage after the pattern */
|
||||
};
|
||||
|
||||
/* depth types */
|
||||
enum ase_awk_depth_t
|
||||
{
|
||||
ASE_AWK_DEPTH_BLOCK = (1 << 0),
|
||||
ASE_AWK_DEPTH_EXPR = (1 << 1)
|
||||
};
|
||||
/* extio types */
|
||||
enum ase_awk_extio_type_t
|
||||
{
|
||||
@ -364,6 +370,7 @@ ase_size_t ase_awk_getsrcline (ase_awk_t* awk);
|
||||
int ase_awk_getopt (ase_awk_t* awk);
|
||||
void ase_awk_setopt (ase_awk_t* awk, int opt);
|
||||
|
||||
void ase_awk_setmaxparsedepth (ase_awk_t*, int types, ase_size_t depth);
|
||||
int ase_awk_parse (ase_awk_t* awk, ase_awk_srcios_t* srcios);
|
||||
|
||||
/*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: awk_i.h,v 1.84 2006-11-24 15:22:33 bacon Exp $
|
||||
* $Id: awk_i.h,v 1.85 2006-11-25 15:51:30 bacon Exp $
|
||||
*/
|
||||
|
||||
#ifndef _ASE_AWK_AWKI_H_
|
||||
@ -116,8 +116,18 @@ struct ase_awk_t
|
||||
|
||||
struct
|
||||
{
|
||||
ase_size_t loop;
|
||||
ase_size_t expr; /* expression */
|
||||
struct
|
||||
{
|
||||
ase_size_t block;
|
||||
ase_size_t loop;
|
||||
ase_size_t expr; /* expression */
|
||||
} cur;
|
||||
|
||||
struct
|
||||
{
|
||||
ase_size_t block;
|
||||
ase_size_t expr;
|
||||
} max;
|
||||
} depth;
|
||||
|
||||
ase_awk_tab_t globals;
|
||||
@ -126,6 +136,8 @@ struct ase_awk_t
|
||||
ase_size_t nlocals_max;
|
||||
|
||||
int nl_semicolon;
|
||||
|
||||
ase_awk_nde_t* (*parse_block) (ase_awk_t*,ase_bool_t);
|
||||
} parse;
|
||||
|
||||
/* source code management */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: jni.c,v 1.24 2006-11-24 15:04:23 bacon Exp $
|
||||
* $Id: jni.c,v 1.25 2006-11-25 15:51:30 bacon Exp $
|
||||
*/
|
||||
|
||||
#include <ase/awk/jni.h>
|
||||
@ -243,6 +243,7 @@ JNIEXPORT void JNICALL Java_ase_awk_Awk_parse (JNIEnv* env, jobject obj)
|
||||
srcios.out = __write_source;
|
||||
srcios.custom_data = &srcio_data;
|
||||
|
||||
ase_awk_setmaxparsedepth (awk, ASE_AWK_DEPTH_BLOCK, 10);
|
||||
if (ase_awk_parse (awk, &srcios) == -1)
|
||||
{
|
||||
printf ("parse error.......\n");
|
||||
@ -429,6 +430,7 @@ static ase_ssize_t __call_java_write_source (
|
||||
thrown = (*env)->ExceptionOccurred (env);
|
||||
if (thrown)
|
||||
{
|
||||
(*env)->ExceptionDescribe (env);
|
||||
(*env)->ExceptionClear (env);
|
||||
ret = -1;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: parse.c,v 1.208 2006-11-24 15:07:18 bacon Exp $
|
||||
* $Id: parse.c,v 1.209 2006-11-25 15:51:30 bacon Exp $
|
||||
*/
|
||||
|
||||
#include <ase/awk/awk_i.h>
|
||||
@ -138,6 +138,7 @@ static ase_awk_chain_t* __parse_pattern_block (
|
||||
ase_awk_t* awk, ase_awk_nde_t* ptn, ase_bool_t blockless);
|
||||
|
||||
static ase_awk_nde_t* __parse_block (ase_awk_t* awk, ase_bool_t is_top);
|
||||
static ase_awk_nde_t* __parse_block_dc (ase_awk_t* awk, ase_bool_t is_top);
|
||||
static ase_awk_nde_t* __parse_statement (ase_awk_t* awk);
|
||||
static ase_awk_nde_t* __parse_statement_nb (ase_awk_t* awk);
|
||||
|
||||
@ -321,21 +322,38 @@ static struct __bvent __bvtab[] =
|
||||
#define PANIC(awk,code) \
|
||||
do { (awk)->errnum = (code); return ASE_NULL; } while (0)
|
||||
|
||||
void ase_awk_setmaxparsedepth (ase_awk_t* awk, int types, ase_size_t depth)
|
||||
{
|
||||
if (types & ASE_AWK_DEPTH_BLOCK)
|
||||
{
|
||||
awk->parse.depth.max.block = depth;
|
||||
if (depth <= 0)
|
||||
awk->parse.parse_block = __parse_block;
|
||||
else
|
||||
awk->parse.parse_block = __parse_block_dc;
|
||||
}
|
||||
|
||||
if (types & ASE_AWK_DEPTH_EXPR)
|
||||
{
|
||||
awk->parse.depth.max.expr = depth;
|
||||
}
|
||||
}
|
||||
|
||||
int ase_awk_parse (ase_awk_t* awk, ase_awk_srcios_t* srcios)
|
||||
{
|
||||
int n;
|
||||
|
||||
ASE_AWK_ASSERT (awk, srcios != ASE_NULL && srcios->in != ASE_NULL);
|
||||
ASE_AWK_ASSERT (awk, awk->parse.depth.loop == 0);
|
||||
ASE_AWK_ASSERT (awk, awk->parse.depth.expr == 0);
|
||||
ASE_AWK_ASSERT (awk, awk->parse.depth.cur.loop == 0);
|
||||
ASE_AWK_ASSERT (awk, awk->parse.depth.cur.expr == 0);
|
||||
|
||||
ase_awk_clear (awk);
|
||||
ASE_AWK_MEMCPY (awk, &awk->src.ios, srcios, ase_sizeof(awk->src.ios));
|
||||
|
||||
n = __parse (awk);
|
||||
|
||||
ASE_AWK_ASSERT (awk, awk->parse.depth.loop == 0);
|
||||
ASE_AWK_ASSERT (awk, awk->parse.depth.expr == 0);
|
||||
ASE_AWK_ASSERT (awk, awk->parse.depth.cur.loop == 0);
|
||||
ASE_AWK_ASSERT (awk, awk->parse.depth.cur.expr == 0);
|
||||
|
||||
return n;
|
||||
}
|
||||
@ -430,7 +448,7 @@ static ase_awk_t* __parse_progunit (ase_awk_t* awk)
|
||||
function name (parameter-list) { statement }
|
||||
*/
|
||||
|
||||
ASE_AWK_ASSERT (awk, awk->parse.depth.loop == 0);
|
||||
ASE_AWK_ASSERT (awk, awk->parse.depth.cur.loop == 0);
|
||||
|
||||
if ((awk->option & ASE_AWK_EXPLICIT) && MATCH(awk,TOKEN_GLOBAL))
|
||||
{
|
||||
@ -767,7 +785,7 @@ static ase_awk_nde_t* __parse_function (ase_awk_t* awk)
|
||||
}
|
||||
|
||||
/* actual function body */
|
||||
body = __parse_block (awk, ase_true);
|
||||
body = awk->parse.parse_block (awk, ase_true);
|
||||
if (body == ASE_NULL)
|
||||
{
|
||||
ASE_AWK_FREE (awk, name_dup);
|
||||
@ -792,7 +810,7 @@ static ase_awk_nde_t* __parse_function (ase_awk_t* awk)
|
||||
afn->name = ASE_NULL; /* function name set below */
|
||||
afn->name_len = 0;
|
||||
afn->nargs = nargs;
|
||||
afn->body = body;
|
||||
afn->body = body;
|
||||
|
||||
n = ase_awk_map_putx (&awk->tree.afns, name_dup, name_len, afn, &pair);
|
||||
if (n < 0)
|
||||
@ -820,7 +838,7 @@ static ase_awk_nde_t* __parse_begin (ase_awk_t* awk)
|
||||
ASE_AWK_ASSERT (awk, MATCH(awk,TOKEN_LBRACE));
|
||||
|
||||
if (__get_token(awk) == -1) return ASE_NULL;
|
||||
nde = __parse_block(awk, ase_true);
|
||||
nde = awk->parse.parse_block (awk, ase_true);
|
||||
if (nde == ASE_NULL) return ASE_NULL;
|
||||
|
||||
awk->tree.begin = nde;
|
||||
@ -834,7 +852,7 @@ static ase_awk_nde_t* __parse_end (ase_awk_t* awk)
|
||||
ASE_AWK_ASSERT (awk, MATCH(awk,TOKEN_LBRACE));
|
||||
|
||||
if (__get_token(awk) == -1) return ASE_NULL;
|
||||
nde = __parse_block(awk, ase_true);
|
||||
nde = awk->parse.parse_block (awk, ase_true);
|
||||
if (nde == ASE_NULL) return ASE_NULL;
|
||||
|
||||
awk->tree.end = nde;
|
||||
@ -852,7 +870,7 @@ static ase_awk_chain_t* __parse_pattern_block (
|
||||
{
|
||||
ASE_AWK_ASSERT (awk, MATCH(awk,TOKEN_LBRACE));
|
||||
if (__get_token(awk) == -1) return ASE_NULL;
|
||||
nde = __parse_block(awk, ase_true);
|
||||
nde = awk->parse.parse_block (awk, ase_true);
|
||||
if (nde == ASE_NULL) return ASE_NULL;
|
||||
}
|
||||
|
||||
@ -1006,6 +1024,25 @@ and merged to top-level block */
|
||||
return (ase_awk_nde_t*)block;
|
||||
}
|
||||
|
||||
static ase_awk_nde_t* __parse_block_dc (ase_awk_t* awk, ase_bool_t is_top)
|
||||
{
|
||||
ase_awk_nde_t* nde;
|
||||
|
||||
ASE_AWK_ASSERT (awk, awk->parse.depth.max.block > 0);
|
||||
|
||||
if (awk->parse.depth.cur.block >= awk->parse.depth.max.block)
|
||||
{
|
||||
awk->errnum = ASE_AWK_ERECURSION;
|
||||
return ASE_NULL;
|
||||
}
|
||||
|
||||
awk->parse.depth.cur.block++;
|
||||
nde = __parse_block (awk, is_top);
|
||||
awk->parse.depth.cur.block--;
|
||||
|
||||
return nde;
|
||||
}
|
||||
|
||||
static ase_awk_t* __add_builtin_globals (ase_awk_t* awk)
|
||||
{
|
||||
struct __bvent* p = __bvtab;
|
||||
@ -1195,7 +1232,7 @@ static ase_awk_nde_t* __parse_statement (ase_awk_t* awk)
|
||||
else if (MATCH(awk,TOKEN_LBRACE))
|
||||
{
|
||||
if (__get_token(awk) == -1) return ASE_NULL;
|
||||
nde = __parse_block (awk, ase_false);
|
||||
nde = awk->parse.parse_block (awk, ase_false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1223,9 +1260,9 @@ static ase_awk_nde_t* __parse_statement_nb (ase_awk_t* awk)
|
||||
{
|
||||
if (__get_token(awk) == -1) return ASE_NULL;
|
||||
|
||||
awk->parse.depth.loop++;
|
||||
awk->parse.depth.cur.loop++;
|
||||
nde = __parse_while (awk);
|
||||
awk->parse.depth.loop--;
|
||||
awk->parse.depth.cur.loop--;
|
||||
|
||||
return nde;
|
||||
}
|
||||
@ -1233,9 +1270,9 @@ static ase_awk_nde_t* __parse_statement_nb (ase_awk_t* awk)
|
||||
{
|
||||
if (__get_token(awk) == -1) return ASE_NULL;
|
||||
|
||||
awk->parse.depth.loop++;
|
||||
awk->parse.depth.cur.loop++;
|
||||
nde = __parse_for (awk);
|
||||
awk->parse.depth.loop--;
|
||||
awk->parse.depth.cur.loop--;
|
||||
|
||||
return nde;
|
||||
}
|
||||
@ -1246,9 +1283,9 @@ awk->parse.nl_semicolon = 1;
|
||||
{
|
||||
if (__get_token(awk) == -1) return ASE_NULL;
|
||||
|
||||
awk->parse.depth.loop++;
|
||||
awk->parse.depth.cur.loop++;
|
||||
nde = __parse_dowhile (awk);
|
||||
awk->parse.depth.loop--;
|
||||
awk->parse.depth.cur.loop--;
|
||||
|
||||
return nde;
|
||||
}
|
||||
@ -1332,9 +1369,9 @@ static ase_awk_nde_t* __parse_expression (ase_awk_t* awk)
|
||||
{
|
||||
ase_awk_nde_t* nde;
|
||||
|
||||
awk->parse.depth.expr++;
|
||||
awk->parse.depth.cur.expr++;
|
||||
nde = __parse_expression0 (awk);
|
||||
awk->parse.depth.expr--;
|
||||
awk->parse.depth.cur.expr--;
|
||||
|
||||
return nde;
|
||||
}
|
||||
@ -2302,7 +2339,7 @@ static ase_awk_nde_t* __parse_primary (ase_awk_t* awk)
|
||||
|
||||
if ((awk->parse.id.stmnt != TOKEN_PRINT &&
|
||||
awk->parse.id.stmnt != TOKEN_PRINTF) ||
|
||||
awk->parse.depth.expr != 1)
|
||||
awk->parse.depth.cur.expr != 1)
|
||||
{
|
||||
if (!MATCH(awk,TOKEN_IN))
|
||||
{
|
||||
@ -3101,7 +3138,7 @@ static ase_awk_nde_t* __parse_break (ase_awk_t* awk)
|
||||
{
|
||||
ase_awk_nde_break_t* nde;
|
||||
|
||||
if (awk->parse.depth.loop <= 0) PANIC (awk, ASE_AWK_EBREAK);
|
||||
if (awk->parse.depth.cur.loop <= 0) PANIC (awk, ASE_AWK_EBREAK);
|
||||
|
||||
nde = (ase_awk_nde_break_t*) ASE_AWK_MALLOC (awk, ase_sizeof(ase_awk_nde_break_t));
|
||||
if (nde == ASE_NULL) PANIC (awk, ASE_AWK_ENOMEM);
|
||||
@ -3115,7 +3152,7 @@ static ase_awk_nde_t* __parse_continue (ase_awk_t* awk)
|
||||
{
|
||||
ase_awk_nde_continue_t* nde;
|
||||
|
||||
if (awk->parse.depth.loop <= 0) PANIC (awk, ASE_AWK_ECONTINUE);
|
||||
if (awk->parse.depth.cur.loop <= 0) PANIC (awk, ASE_AWK_ECONTINUE);
|
||||
|
||||
nde = (ase_awk_nde_continue_t*) ASE_AWK_MALLOC (
|
||||
awk, ase_sizeof(ase_awk_nde_continue_t));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: Awk.java,v 1.9 2006-11-24 15:40:54 bacon Exp $
|
||||
* $Id: Awk.java,v 1.10 2006-11-25 15:51:57 bacon Exp $
|
||||
*/
|
||||
|
||||
package ase.test.awk;
|
||||
@ -42,6 +42,13 @@ public class Awk extends ase.awk.StdAwk
|
||||
return cout;
|
||||
}
|
||||
|
||||
/*
|
||||
protected String getDeparsedSourceName ()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
*/
|
||||
|
||||
public static void main (String[] args)
|
||||
{
|
||||
Awk awk = null;
|
||||
|
Loading…
Reference in New Issue
Block a user