PostgreSQL Source Code: src/bin/psql/psqlscanslash.l Source File (original) (raw)

1%top{

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

20

21#include <ctype.h>

22

25

28

30}

31

32%{

34

35

36

37

38

40

41

42

43

44

49

50

51

52#define LEXRES_EOL 0

53#define LEXRES_OK 1

54

55

57

58#define ECHO psqlscan_emit(cur_state, yytext, yyleng)

59

60

61

static int backtick_start_offset

static int unquoted_option_chars

static char * option_quote

static enum slash_option_type option_type

static void evaluate_backtick(PsqlScanState state)

62%}

63

64

65%option reentrant

66%option bison-bridge

67%option 8bit

68%option never-interactive

69%option nodefault

70%option noinput

71%option nounput

72%option noyywrap

73%option warn

74%option prefix="slash_yy"

75

76

77

78

79

80%option extra-type="PsqlScanState"

81

82

83

84

85

86

87

88

89

90

91

92%x xslashcmd

93%x xslashargstart

94%x xslasharg

95%x xslashquote

96%x xslashbackquote

97%x xslashdquote

98%x xslashwholeline

99%x xslashend

100

101

102

103

104space [ \t\n\r\f\v]

105quote '

106xeoctesc [\\][0-7]{1,3}

107xehexesc [\\]x[0-9A-Fa-f]{1,2}

108xqdouble {quote}{quote}

109dquote \"

110variable_char [A-Za-z\200-\377_0-9]

111

112other .

113

115

116%{

117

118 PsqlScanState cur_state = yyextra;

119 PQExpBuffer output_buf = cur_state->output_buf;

120

121

122

123

124

125

126

127

128 BEGIN(cur_state->start_state);

129%}

130

131

132

133

134

135

136{other}|\n { ECHO; }

137

138

139

140

141

142{

143

144

145{space}|"\\" {

146 yyless(0);

147 cur_state->start_state = YY_START;

149 }

150

151{other} { ECHO; }

152

153}

154

155{

156

157

158

159

160

161

162{space}+ { }

163

164"|" {

166 {

167

169 BEGIN(xslashwholeline);

170 }

171 else

172 {

173

174 yyless(0);

175 BEGIN(xslasharg);

176 }

177 }

178

179{other} {

180 yyless(0);

181 BEGIN(xslasharg);

182 }

183

184}

185

186{

187

188

189

190

191

192

193

194

195{space}|"\\" {

196

197

198

199

200

201

202

203

204

205 yyless(0);

206 cur_state->start_state = YY_START;

208 }

209

210{quote} {

213 BEGIN(xslashquote);

214 }

215

216"`" {

220 BEGIN(xslashbackquote);

221 }

222

223{dquote} {

227 BEGIN(xslashdquote);

228 }

229

230:{variable_char}+ {

231

232 if (cur_state->callbacks->get_variable == NULL)

234 else

235 {

236 char *varname;

238

240 yytext + 1,

242 value = cur_state->callbacks->get_variable(varname,

244 cur_state->cb_passthrough);

245 free(varname);

246

247

248

249

250

251

252

253

255 {

258 }

259 else

261

263 }

265 }

void appendPQExpBufferStr(PQExpBuffer str, const char *data)

char * psqlscan_extract_substring(PsqlScanState state, const char *txt, int len)

266

267:'{variable_char}+' {

272 }

void psqlscan_escape_variable(PsqlScanState state, const char *txt, int len, PsqlScanQuoteType quote)

273

274

275:\"{variable_char}+\" {

280 }

281

282:\{\?{variable_char}+\} {

284 }

void psqlscan_test_variable(PsqlScanState state, const char *txt, int len)

285

286:'{variable_char}* {

287

288 yyless(1);

291 }

292

293:\"{variable_char}* {

294

295 yyless(1);

298 }

299

300:\{\?{variable_char}* {

301

302 yyless(1);

305 }

306

307:\{ {

308

309 yyless(1);

312 }

313

314{other} {

317 }

318

319}

320

321{

322

323

324

325

326

327{quote} { BEGIN(xslasharg); }

328

void appendPQExpBufferChar(PQExpBuffer str, char ch)

330

336

337{xeoctesc} {

338

340 (char) strtol(yytext + 1, NULL, 8));

341 }

342

343{xehexesc} {

344

346 (char) strtol(yytext + 2, NULL, 16));

347 }

348

349"\\". { psqlscan_emit(cur_state, yytext + 1, 1); }

void psqlscan_emit(PsqlScanState state, const char *txt, int len)

350

351{other}|\n { ECHO; }

352

353}

354

355{

356

357

358

359

360

361"`" {

362

363 if (cur_state->cb_passthrough == NULL ||

366 BEGIN(xslasharg);

367 }

bool conditional_active(ConditionalStack cstack)

368

369:{variable_char}+ {

370

371 if (cur_state->callbacks->get_variable == NULL)

373 else

374 {

375 char *varname;

377

379 yytext + 1,

381 value = cur_state->callbacks->get_variable(varname,

383 cur_state->cb_passthrough);

384 free(varname);

385

387 {

390 }

391 else

393 }

394 }

395

396:'{variable_char}+' {

399 }

400

401:'{variable_char}* {

402

403 yyless(1);

405 }

406

407{other}|\n { ECHO; }

408

409}

410

411{

412

413

414{dquote} {

416 BEGIN(xslasharg);

417 }

418

419{other}|\n { ECHO; }

420

421}

422

423{

424

425

426

427{space}+ {

428 if (output_buf->len > 0)

430 }

431

432{other} { ECHO; }

433

434}

435

436{

437

438

439"\\\\" {

440 cur_state->start_state = YY_START;

442 }

443

444{other}|\n {

445 yyless(0);

446 cur_state->start_state = YY_START;

448 }

449

450}

451

452<> {

453 if (cur_state->buffer_stack == NULL)

454 {

455 cur_state->start_state = YY_START;

456 return LEXRES_EOL;

457 }

458

459

460

461

462

465 }

void psqlscan_select_top_buffer(PsqlScanState state)

void psqlscan_pop_buffer_stack(PsqlScanState state)

466

467%%

468

469

470

471

472

473

474

475

476

477

478

479char *

481{

483

484

486

487

489

490

491 state->output_buf = &mybuf;

492

493

494 if (state->buffer_stack != NULL)

495 yy_switch_to_buffer(state->buffer_stack->buf, state->scanner);

496 else

497 yy_switch_to_buffer(state->scanbufhandle, state->scanner);

498

499

500

501

502

503 state->start_state = xslashcmd;

504

505

507

508

509

510

511

512

513

515

516 return mybuf.data;

517}

518

519

520

521

522

523

524

525

526

527

528

529

530

531

532

533

534

535

536

537

538char *

541 char *quote,

543{

546 int final_state;

547 char local_quote;

548

549

551

552 if (quote == NULL)

553 quote = &local_quote;

554 *quote = 0;

555

556

558

559

563

564

565 state->output_buf = &mybuf;

566

567

568 if (state->buffer_stack != NULL)

569 yy_switch_to_buffer(state->buffer_stack->buf, state->scanner);

570 else

571 yy_switch_to_buffer(state->scanbufhandle, state->scanner);

572

573

575 state->start_state = xslashwholeline;

576 else

577 state->start_state = xslashargstart;

578

579

580 lexresult = yylex(NULL, state->scanner);

581

582

583 final_state = state->start_state;

584

585

586

587

588

590

591

592

593

594

595

597

598 switch (final_state)

599 {

600 case xslashargstart:

601

602 break;

603 case xslasharg:

604

606 {

608 mybuf.len > 0 &&

609 mybuf.data[mybuf.len - 1] == ';')

610 {

611 mybuf.data[--mybuf.len] = '\0';

612 }

613 }

614

615

616

617

618

620 {

623 state->encoding);

624

625 mybuf.len = strlen(mybuf.data);

626 }

627 break;

628 case xslashquote:

629 case xslashbackquote:

630 case xslashdquote:

631

634 return NULL;

635 case xslashwholeline:

636

637

638

639

640

641

642

644 {

645 while (mybuf.len > 0 &&

646 (mybuf.data[mybuf.len - 1] == ';' ||

647 (isascii((unsigned char) mybuf.data[mybuf.len - 1]) &&

648 isspace((unsigned char) mybuf.data[mybuf.len - 1]))))

649 {

650 mybuf.data[--mybuf.len] = '\0';

651 }

652 }

653 break;

654 default:

655

656 fprintf(stderr, "invalid YY_START\n");

657 exit(1);

658 }

659

660

661

662

663

664 if (mybuf.len == 0 && *quote == 0)

665 {

667 return NULL;

668 }

669

670

671 return mybuf.data;

672}

673

674

675

676

677void

679{

680

682

683

684 state->output_buf = NULL;

685

686

687 if (state->buffer_stack != NULL)

688 yy_switch_to_buffer(state->buffer_stack->buf, state->scanner);

689 else

690 yy_switch_to_buffer(state->scanbufhandle, state->scanner);

691

692

693 state->start_state = xslashend;

694

695

697

698

699

700

701

702

703

705}

706

707

708

709

710int

712{

713 return state->paren_depth;

714}

715

716

717

718

719void

721{

723 state->paren_depth = depth;

724}

725

726

727

728

729

730

731

732

733

734

735

736

737

738

739

740

741

742void

744{

745 bool inquotes = false;

746 char *cp = str;

747

748 while (*cp)

749 {

750 if (*cp == '"')

751 {

752 if (inquotes && cp[1] == '"')

753 {

754

755 cp++;

756 }

757 else

758 inquotes = !inquotes;

759

760 memmove(cp, cp + 1, strlen(cp));

761

762 }

763 else

764 {

765 if (downcase && !inquotes)

766 *cp = pg_tolower((unsigned char) *cp);

768 }

769 }

770}

771

772

773

774

775

776

777

778static void

780{

784 FILE *fd;

785 bool error = false;

786 int exit_code = 0;

787 char buf[512];

788 size_t result;

789

791

792 fflush(NULL);

793 fd = popen(cmd, "r");

794 if (fd)

795 {

798 exit_code = -1;

799 }

800

802 {

803 do

804 {

805 result = fread(buf, 1, sizeof(buf), fd);

806 if (ferror(fd))

807 {

810 break;

811 }

813 } while (!feof(fd));

814 }

815

816 if (fd)

817 {

818

819

820

821

822

823 exit_code = pclose(fd);

824 if (exit_code == -1)

825 {

828 }

829 }

830

832 {

835 }

836

837

839 output_buf->data[output_buf->len] = '\0';

840

841

843 {

844

845 if (cmd_output.len > 0 &&

846 cmd_output.data[cmd_output.len - 1] == '\n')

847 cmd_output.len--;

849 }

850

851

853

855}

void SetShellResultVariables(int wait_result)

#define PG_USED_FOR_ASSERTS_ONLY

#define fprintf(file, fmt, msg)

int PQmblenBounded(const char *s, int encoding)

Assert(PointerIsAligned(start, uint64))

#define pg_log_error(...)

unsigned char pg_tolower(unsigned char ch)

void initPQExpBuffer(PQExpBuffer str)

void appendBinaryPQExpBuffer(PQExpBuffer str, const char *data, size_t datalen)

void termPQExpBuffer(PQExpBuffer str)

#define PQExpBufferDataBroken(buf)

static int fd(const char *x, int i)

void psql_scan_reselect_sql_lexer(PsqlScanState state)

void psql_scan_slash_command_end(PsqlScanState state)

void psql_scan_set_paren_depth(PsqlScanState state, int depth)

void dequote_downcase_identifier(char *str, bool downcase, int encoding)

int yylex(YYSTYPE *yylval_param, yyscan_t yyscanner)

char * psql_scan_slash_option(PsqlScanState state, enum slash_option_type type, char *quote, bool semicolon)

int psql_scan_get_paren_depth(PsqlScanState state)

char * psql_scan_slash_command(PsqlScanState state)