short SetTerminalCharset::process(SqlciEnv * sqlci_env) { HandleCLIErrorInit(); char* tcs = get_argument(); Int32 tcs_len; #pragma nowarn(1506) // warning elimination if ( tcs != NULL && ((tcs_len=strlen(tcs)) <= 128) ) #pragma warn(1506) // warning elimination { char tcs_uppercase[129]; str_cpy_convert(tcs_uppercase, tcs, tcs_len, 1); tcs_uppercase[tcs_len] = 0; if ( CharInfo::isCharSetSupported(tcs_uppercase) == FALSE ) { SqlciError (SQLCI_INVALID_TERMINAL_CHARSET_NAME_ERROR, (ErrorParam *) 0 ); return 0; } if ( CharInfo::isTerminalCharSetSupported(tcs_uppercase) == FALSE ) { ErrorParam *ep = new ErrorParam(tcs); SqlciError (2038, ep, (ErrorParam *) 0 ); delete ep; return 0; } // The following code had been commented out but has been restored // for the charset project CQD removed on 12/11/2007 /* char cqd_stmt[200]; // charset name can be up to 128 bytes long sprintf(cqd_stmt, "CONTROL QUERY DEFAULT TERMINAL_CHARSET '%s';", tcs_uppercase ); long retcode = SqlCmd::executeQuery(cqd_stmt, sqlci_env); if ( retcode == 0 )*/ sqlci_env -> setTerminalCharset( CharInfo::getCharSetEnum(tcs_uppercase) ); // else // HandleCLIError(retcode, sqlci_env); } else SqlciError (SQLCI_INVALID_TERMINAL_CHARSET_NAME_ERROR, (ErrorParam *) 0 ); return 0; }
short Mode::process_report(SqlciEnv * sqlci_env) { if (sqlci_env->isReportWriterMode()) { SqlciError(SQLCI_RW_MODE_ALREADY_REPORT ,(ErrorParam *) 0 ); return 0; } // If we are in MXCS mode and are switching to RW mode, // make sure that that MACL knows that they have to stop // the existing context for that. CR 10-040311-7309 // 64-bit: macl is no longer supported // if (sqlci_env->isMXCSMode()) // CS_MXCI_StopContext(sqlci_env->sqlciCSEnv()->csEnv()); sqlci_env->setMode(SqlciEnv::REPORT_); if (sqlci_env->get_logfile()->IsOpen()) { // retcode should be 0 for success and -1 for error. // 64bit: no more report writer, return -1 // long retcode = RW_MXCI_sendOutputDevice (sqlci_env->sqlciRWEnv()->rwEnv(), sqlci_env, LOG_FILE); Lng32 retcode = -1; if (retcode) // retcode == -1 { SqlciError (SQLCI_RW_INVALID_OUTPUT_DEVICE,(ErrorParam *) 0 ); } } return 0; }
short SetIsoMapping::process(SqlciEnv * sqlci_env) { HandleCLIErrorInit(); char* omcs = get_argument(); Int32 omcs_len; #pragma nowarn(1506) // warning elimination if ( omcs != NULL && ((omcs_len=strlen(omcs)) <= 128) ) #pragma warn(1506) // warning elimination { char omcs_uppercase[129]; str_cpy_convert(omcs_uppercase, omcs, omcs_len, 1); omcs_uppercase[omcs_len] = 0; if ( strcmp(omcs_uppercase, "ISO88591") != 0 ) { // 15001 42000 99999 BEGINNER MAJOR DBADMIN // A syntax error occurred at or before: $0~string0 ErrorParam *ep = new ErrorParam(omcs); SqlciError (15001, ep, (ErrorParam *) 0 ); delete ep; return 0; } } else { // 15001 42000 99999 BEGINNER MAJOR DBADMIN // A syntax error occurred at or before: $0~string0 ErrorParam *ep; if (omcs) ep = new ErrorParam(omcs); else ep = new ErrorParam("ISO_MAPPING"); SqlciError (15001, ep, (ErrorParam *) 0 ); delete ep; } return 0; }
short Mode::process(SqlciEnv * sqlci_env) { short retcode = 1; switch (type) { // 64-bit: report writer are no longer supported /* // case REPORT_: // retcode = process_report(sqlci_env); // break; */ case SQL_: retcode = process_sql(sqlci_env); break; case DISPLAY_: retcode = process_display(sqlci_env); break; //Neo 2.0: MODE MXCS should be disabled in Neo Soln 10-061220-1308. /*case MXCS_: retcode = process_mxcs(sqlci_env); break; */ default: SqlciError(SQLCI_INVALID_MODE ,(ErrorParam *) 0 ); break; } return retcode; }
short Mode::process_mxcs(SqlciEnv * sqlci_env) { if (sqlci_env->isMXCSMode()) { SqlciError(SQLCI_CS_MODE_ALREADY_MXCS ,(ErrorParam *) 0 ); return 0; } else { if (sqlci_env->statusTransaction()) { SqlciError(SQLCI_TRANSACTION_IN_PROGRESS ,(ErrorParam *) 0 ); return 0; } sqlci_env->setMode(SqlciEnv::MXCS_); return 0; } }
Int32 sqlci_parser_handle_report_writer(SqlciEnv *sqlci_env, Lng32 retval) { // if success in parsing so far and we have a valid SqlciParseTree which // is a SqlciNode then you check for RW mode or MACL/MXCS mode. if (!retval) { if ( (sqlci_env->sqlciRWEnv()->isSelectInProgress()) && !(SqlciParseTree->isAllowedInSIP()) ) { SqlciError (SQLCI_RW_SELECT_IN_PROGRESS, (ErrorParam *) 0 ); delete SqlciParseTree; SqlciParseTree = NULL; return 0; } else if ( !(sqlci_env->sqlciRWEnv()->isSelectInProgress()) && !(SqlciParseTree->isAllowedInRWMode()) ) { SqlciError (SQLCI_RW_ALLOWED_ONLY_DURING_SIP, (ErrorParam *) 0 ); delete SqlciParseTree; SqlciParseTree = NULL; return 0; } else if ((sqlci_env->isMXCSMode()) && !(SqlciParseTree->isAllowedInCSMode())) { delete SqlciParseTree; SqlciParseTree = (SqlciNode *)new SqlciCSQueryCmd(SqlciParse_OriginalStr, (Lng32)strlen(SqlciParse_OriginalStr)); assert(SqlciParseTree->isSqlciNode()); return 1; } else return 1; } else return 1; }
short SetDefine::process(SqlciEnv * sqlci_env) { Define * define_ = sqlci_env->get_definelist()->get(define_name); if (alter_) { if (NOT define_) { SqlciError(SQLCI_DEFINE_DOESNT_EXIST, (ErrorParam*)NULL); return 0; } // reset this define #pragma nowarn(1506) // warning elimination Reset r(Reset::DEFINE_, define_name, strlen(define_name)); #pragma warn(1506) // warning elimination r.process(sqlci_env); } else { // add define if (define_) { SqlciError(SQLCI_DEFINE_EXISTS, (ErrorParam*)NULL); // (new ErrorParam(define_name))); return 0; } } define_ = new Define(define_name, get_argument()); if (define_->set(sqlci_env)) { // error case SqlciError (SQLCI_DEFINE_ERROR, (ErrorParam*)NULL); } sqlci_env->get_definelist()->append(define_); return 0; }
void InputStmt::syntaxErrorOnMissingQuote(char * str) { if (!str) str = getPackedString(); SqlciError (SQLCI_INPUT_MISSING_QUOTE, (ErrorParam *) 0); size_t quote_pos = 0; findEnd(str, quote_pos); // subtract one from quote_pos to convert 1-based offset to 0-based #pragma nowarn(1506) // warning elimination StoreSyntaxError(str, --quote_pos, sqlci_DA); #pragma warn(1506) // warning elimination sqlci_parser_syntax_error_cleanup(NULL,sqlci_env); } // syntaxErrorOnMissingQuote
short Mode::process_sql(SqlciEnv * sqlci_env) { if (SqlciEnv::SQL_ == sqlci_env->getMode()) { SqlciError(SQLCI_RW_MODE_ALREADY_SQL ,(ErrorParam *) 0 ); return 0; } // If we are in MXCS mode and are switching to SQL mode // make sure that MACL knows that they have to stop // the existing context for that. CR 10-040311-7309 // 64bit: no more macl // if (sqlci_env->isMXCSMode()) // CS_MXCI_StopContext(sqlci_env->sqlciCSEnv()->csEnv()); sqlci_env->setMode(SqlciEnv::SQL_); sqlci_env->sqlciRWEnv()->setSelectInProgress(FALSE); return 0; }
////////////////////////////////////// // Append a bogus string ("!" is an illegal SQL_TEXT character) // to a copy of the unterminated string // so the parser is guaranteed to exit with a syntax error message. // Note that since this is to be called only on EOF, // we assume this InputStmt will not be saved on the history list // so there's no need to append <bangeof> to its fragment list and repack it. ////////////////////////////////////// void InputStmt::syntaxErrorOnEof(const char * str) { // We must embed a space in obeybangeof, else an unterminated OBEY cmd // will hang forever (because of the sqlci lexer's special <FNAME> state, // called by sqlci_parser_syntax_error_cleanup). #define bangeof " !EOF!" #define obeybangeof " !EOF EOF!" if (!str) str = getPackedString(); char * err; err = new char[strlen(str) + strlen(bangeof) + 2]; // +2: \n, \0 strcpy(err,"\n"); strcat(err,str); strcat(err,bangeof); ErrorParam *p1 = new ErrorParam (err); SqlciError (SQLCI_INPUT_PREMATURE_EOF, p1, (ErrorParam *) 0 ); delete p1; delete [] err; } // syntaxErrorOnEof
short Help::process(SqlciEnv * sqlci_env) { // help is not yet supported from MXCI. SqlciError (SQLCI_HELP_NOT_FOUND, (ErrorParam *) 0); return 0; #pragma nowarn(269) // warning elimination char * topic_name = get_argument(); #pragma warn(269) // warning elimination short topic_len ; short open_err ; short read_err ; short fnum ; char fname[36] ; // Maximum filename length, including terminating null char pnum[9] ; char * alt_msgfile; short symbol = 0 ; short lang = 0 ; enum { msg_max_len = 200 } ; char help_msg[msg_max_len] ; short help_msg_len ; short more_lines ; char p1, p2, p3, p4, p5 ; short done = 0 ; struct IMMUkey_def key ; strcpy (pnum, "T9197X00"); alt_msgfile = getenv("SQLMSGFILE"); if (alt_msgfile) strcpy (fname, alt_msgfile); else strcpy (fname, "$SYSTEM.SYSTEM.SQLMSG"); #pragma nowarn(1506) // warning elimination topic_len = strlen(topic_name) ; #pragma warn(1506) // warning elimination if (topic_len >= len_HelpTopic) { SqlciError (SQLCI_LONG_HELP_TOPIC, (ErrorParam *) 0); return 0 ; } open_err = IMMU_OPEN_(fname, (short)strlen(fname), &fnum, pnum, &symbol, &lang); if (open_err) { SqlciError (SQLCI_HELP_FOPEN_ERROR, new ErrorParam (open_err), new ErrorParam (&fname[0]) , (ErrorParam *) 0 ); return 0; } // Build the key for message file strcpy (key.IMMUkey_product_number, "T9197X00"); strcpy (key.IMMUkey_record_type, "HL"); key.IMMUkey_key_field1 = 0 ; key.IMMUkey_key_field2 = 1 ; // more memset (key.IMMUkey_key_field3, ' ', sizeof(key.IMMUkey_key_field3)); for (Int32 i=0; i < topic_len; i++) #pragma nowarn(1506) // warning elimination topic_name[i] = tolower(topic_name[i]); #pragma warn(1506) // warning elimination memcpy (key.IMMUkey_key_field3, topic_name, topic_len) ; key.IMMUkey_key_field3[topic_len] = '^' ; switch (type) { case SYNTAX_ : memcpy (&key.IMMUkey_key_field3[topic_len+1], "syntax", 6); break; case EXAMPLE_ : memcpy (&key.IMMUkey_key_field3[topic_len+1], "example", 7); break; case DETAIL_ : memcpy (&key.IMMUkey_key_field3[topic_len+1], "detail", 6); break; } // The key is complete. Read the records now done = 0 ; while (!done) { read_err = IMMU_READ_FORMAT_ (fnum, &key, &help_msg[0], msg_max_len, &help_msg_len, symbol, &more_lines, &p1, &p2, &p3, &p4, &p5) ; if (read_err) { if (read_err == 11) SqlciError (SQLCI_HELP_NOT_FOUND, (ErrorParam *) 0); else SqlciError (SQLCI_HELP_READ_ERROR, new ErrorParam (read_err), new ErrorParam (&fname[0]), (ErrorParam *) 0 ); done = -1; } else { if (help_msg_len == 0) { cout << "\n" ; } else { help_msg[help_msg_len] = (char) 0 ; cout << help_msg << "\n" ; } if (!more_lines) done = -1; } } IMMU_CLOSE_ (fnum); cout << "Help Command : \n" ; cout << " Topic : " << topic_name << "\n" ; cout << " Len : " << strlen(topic_name) << "\n" ; cout << " Type : " ; switch (type) { case SYNTAX_ : cout << "Syntax\n" ; break; case EXAMPLE_ : cout << "Example\n" ; break; case DETAIL_ : cout << "Detail\n" ; break; default : cout << "UNKNOWN type\n" ; break; } cout << "\n" ; return 0 ; };
short FCRepeat::process(SqlciEnv * sqlci_env) { Int32 retval = 0; if (sqlci_env->isOleServer()) { SqlciError (SQLCI_CMD_NOT_SUPPORTED, (ErrorParam *) 0 ); return 0; } // ignore if "!" is in an obey file, or stdin redirected from a file // (should we display an informative error message?) if (!sqlci_env->isInteractiveNow()) #pragma nowarn(1506) // warning elimination return retval; #pragma warn(1506) // warning elimination InputStmt * input_stmt = 0; // Don't add the repeat cmd to the sqlci stmts list. sqlci_env->getSqlciStmts()->remove(); if (cmd != 0) // Character string was provided... { input_stmt = sqlci_env->getSqlciStmts()->get(cmd); } else { if (!cmd_num) input_stmt = sqlci_env->getSqlciStmts()->get(); else { if (neg_num) cmd_num = (sqlci_env->getSqlciStmts()->last_stmt() - cmd_num) + 1; input_stmt = sqlci_env->getSqlciStmts()->get(cmd_num); } } if (input_stmt) { // Log the statement input_stmt->logStmt(); // Add the repeated command to the stmt list // Make a separate copy of the cmd to be repeated; even tho it will not // change, a non-separate copy (i.e. 2 pointers pointing at same entity) // will free same memory twice in ~SqlciStmts (delete InputStmt). InputStmt *new_input_stmt = new InputStmt(sqlci_env); *new_input_stmt = input_stmt; sqlci_env->getSqlciStmts()->add(new_input_stmt); input_stmt->display((UInt16)0); //64bit project: add dummy arg - prevent C++ error SqlciNode * sqlci_node = 0; sqlci_parser(input_stmt->getPackedString(), input_stmt->getPackedString(), &sqlci_node, sqlci_env); if (sqlci_node) { retval = sqlci_node->process(sqlci_env); delete sqlci_node; } } else { SqlciError(SQLCI_NO_STMT_MATCH, (ErrorParam *) 0); } #pragma nowarn(1506) // warning elimination return retval; #pragma warn(1506) // warning elimination }
////////////////////////////////////////////////// // Begin SHAPE /////////////////////////////////////////////////// short Shape::process(SqlciEnv * sqlci_env) { sqlci_env->showShape() = type_; if (! infile_) return 0; // open the infile to read Sql statements from FILE * fStream = 0; fStream = fopen(infile_, "r"); if (!fStream) { ErrorParam *p1 = new ErrorParam (errno); ErrorParam *p2 = new ErrorParam (infile_); SqlciError (SQLCI_OBEY_FOPEN_ERROR, p1, p2, (ErrorParam *) 0 ); delete p1; delete p2; return 0; } // close and remember the current logfile char * logname = NULL; if (sqlci_env->get_logfile()->IsOpen()) { logname = new char[strlen(sqlci_env->get_logfile()->Logname()) + 1]; strcpy(logname, sqlci_env->get_logfile()->Logname()); sqlci_env->get_logfile()->Close(); } // if infile is the same as outfile, generate output into a temp // file(called outfile_ + __temp), and then rename it to infile. // Also, rename infile to infile.bak. NABoolean tempFile = FALSE; char * tempOutfile = NULL; if (outfile_) { if (strcmp(infile_, outfile_) == 0) { tempFile = TRUE; tempOutfile = new char[strlen(outfile_) + strlen("__temp") + 1]; strcpy(tempOutfile, outfile_); strcat(tempOutfile, "__temp"); } else tempOutfile = outfile_; sqlci_env->get_logfile()->Open(tempOutfile, Logfile::CLEAR_); } //////////////////////////////////////////////////////////////// // BEGIN PROCESS NEXT INPUT STMT //////////////////////////////////////////////////////////////// short retcode = processNextStmt(sqlci_env, fStream); if (retcode) { if(logname != NULL) delete [] logname; return retcode; } //////////////////////////////////////////////////////////////// // END PROCESS NEXT INPUT STMT //////////////////////////////////////////////////////////////// fclose(fStream); if (outfile_) { sqlci_env->get_logfile()->Close(); char buf[200]; if (tempFile) { snprintf(buf, 200, "sh mv %s %s.bak", infile_, infile_); ShellCmd * shCmd = new Shell(buf); shCmd->process(sqlci_env); delete shCmd; snprintf(buf, 200, "sh mv %s %s", tempOutfile, infile_); shCmd = new Shell(buf); shCmd->process(sqlci_env); delete shCmd; } } // reopen the original logfile if (logname) sqlci_env->get_logfile()->Open(logname, Logfile::APPEND_); delete [] logname; delete [] tempOutfile; tempOutfile = NULL; return 0; }
short SetInferCharset::process(SqlciEnv * sqlci_env) { HandleCLIErrorInit(); char* ics = get_argument(); Int32 ics_len; #pragma nowarn(1506) // warning elimination if ( ics != NULL && ((ics_len=strlen(ics)) <= 128) ) #pragma warn(1506) // warning elimination { char ics_uppercase[129]; str_cpy_convert(ics_uppercase, ics, ics_len, 1); ics_uppercase[ics_len] = 0; if ( strcmp(ics_uppercase, "FALSE") != 0 && strcmp(ics_uppercase, "TRUE" ) != 0 && strcmp(ics_uppercase, "0" ) != 0 && strcmp(ics_uppercase, "1" ) != 0 ) { // 15001 42000 99999 BEGINNER MAJOR DBADMIN // A syntax error occurred at or before: $0~string0 ErrorParam *ep = new ErrorParam(ics); SqlciError (15001, ep, (ErrorParam *) 0 ); delete ep; return 0; } char cqd_stmt[200]; // charset name can be up to 128 bytes long sprintf(cqd_stmt, "CONTROL QUERY DEFAULT INFER_CHARSET '%s';", ics_uppercase ); Lng32 retcode = SqlCmd::executeQuery(cqd_stmt, sqlci_env); if ( retcode == 0 ) { if ( ics_uppercase[0] == '1' || ics_uppercase[0] == 'T'/*RUE*/) sqlci_env -> setInferCharset(TRUE); else sqlci_env -> setInferCharset(FALSE); } else HandleCLIError(retcode, sqlci_env); } else { // 15001 42000 99999 BEGINNER MAJOR DBADMIN // A syntax error occurred at or before: $0~string0 ErrorParam *ep; if (ics) ep = new ErrorParam(ics); else ep = new ErrorParam("INFER_CHARSET"); SqlciError (15001, ep, (ErrorParam *) 0 ); delete ep; } return 0; }
short SetDefaultCharset::process(SqlciEnv * sqlci_env) { HandleCLIErrorInit(); char* dcs = get_argument(); Int32 dcs_len; #pragma nowarn(1506) // warning elimination if ( dcs != NULL && ((dcs_len=strlen(dcs)) <= 128) ) #pragma warn(1506) // warning elimination { char dcs_uppercase[129]; str_cpy_convert(dcs_uppercase, dcs, dcs_len, 1); dcs_uppercase[dcs_len] = 0; if ( strcmp(dcs_uppercase, "ISO88591") != 0 && strcmp(dcs_uppercase, "UTF8" ) != 0 && strcmp(dcs_uppercase, "SJIS" ) != 0 ) { // 15001 42000 99999 BEGINNER MAJOR DBADMIN // A syntax error occurred at or before: $0~string0 ErrorParam *ep = new ErrorParam(dcs); SqlciError (15001, ep, (ErrorParam *) 0 ); delete ep; return 0; } char cqd_stmt[200]; // charset name can be up to 128 bytes long sprintf(cqd_stmt, "CONTROL QUERY DEFAULT DEFAULT_CHARSET '%s';", dcs_uppercase ); Lng32 retcode = SqlCmd::executeQuery(cqd_stmt, sqlci_env); if ( retcode == 0 ) sqlci_env -> setDefaultCharset(CharInfo::getCharSetEnum(dcs_uppercase)); else HandleCLIError(retcode, sqlci_env); } else { // 15001 42000 99999 BEGINNER MAJOR DBADMIN // A syntax error occurred at or before: $0~string0 ErrorParam *ep; if (dcs) ep = new ErrorParam(dcs); else ep = new ErrorParam("DEFAULT_CHARSET"); SqlciError (15001, ep, (ErrorParam *) 0 ); delete ep; } return 0; }
short FixCommand::process(SqlciEnv * sqlci_env) { Int32 retval = 0; if (sqlci_env->isOleServer()) { SqlciError (SQLCI_CMD_NOT_SUPPORTED, (ErrorParam *) 0 ); return 0; } // ignore if FC is in an obey file, or stdin redirected from a file // (should we display an informative error message?) if (!sqlci_env->isInteractiveNow()) #pragma nowarn(1506) // warning elimination return retval; #pragma warn(1506) // warning elimination InputStmt *input_stmt = 0, *stmt = 0; // Don't add the FC cmd to the sqlci stmts list. sqlci_env->getSqlciStmts()->remove(); if (cmd != 0) // Character string was provided... { input_stmt = sqlci_env->getSqlciStmts()->get(cmd); } else { if (!cmd_num) input_stmt = sqlci_env->getSqlciStmts()->get(); else { if (neg_num) cmd_num = (sqlci_env->getSqlciStmts()->last_stmt() - cmd_num) + 1; input_stmt = sqlci_env->getSqlciStmts()->get(cmd_num); } } if (input_stmt) { enum { DUNNO, YES, NO }; Int32 is_single_stmt = DUNNO; InputStmt * fc_input_stmt = new InputStmt(sqlci_env); *fc_input_stmt = input_stmt; // Prompt user to fix the input stmt. // Fix() value is 0 if we are to execute (and log and history) new stmt, // -20 if user "aborted" the FC via an EOF or "//" at the prompt // (we must emulate this behavior at the -20 section later on!) // if (fc_input_stmt->fix() != -20) { if (!fc_input_stmt->isEmpty()) { // Clear any syntax errors thrown by InputStmt::fix(); // we'll get to 'em one at a time in this loop sqlci_DA.clear(); // Looping, process one or more commands ("a;b;c;") // on the FC input line. char * packedStr = fc_input_stmt->getPackedString(); do { size_t quotePos; // unterminated quote seen? char packedEndC = '\0'; char * packedEnd = fc_input_stmt->findEnd(packedStr, quotePos); if (!quotePos) { // No unterminated quote if (is_single_stmt == DUNNO) is_single_stmt = (!packedEnd || fc_input_stmt->isEmpty(packedEnd)) ? YES : NO; if (packedEnd) // semicolon seen { packedEndC = *packedEnd; *packedEnd = '\0'; if (is_single_stmt == YES && packedEndC) is_single_stmt = NO; } if (!fc_input_stmt->isEmpty(packedStr)) { if (is_single_stmt == YES) stmt = fc_input_stmt; else stmt = new InputStmt(fc_input_stmt, packedStr); Int32 read_error = 0; // Unterminated stmt (no ";" seen), // so prompt for the rest of it. // If user enters EOF in the appended lines, // then log it, but don't history it or execute it. if (!packedEnd) { read_error = stmt->fix(-1/*append_only*/); packedStr = stmt->getPackedString(); } stmt->logStmt(); if (read_error != -20) // see "abort" note above sqlci_env->getSqlciStmts()->add(stmt); if (!read_error) { SqlciNode * sqlci_node = 0; sqlci_parser(packedStr, packedStr, &sqlci_node, sqlci_env); if (sqlci_node) { retval = sqlci_node->process(sqlci_env); delete sqlci_node; } } sqlci_env->displayDiagnostics(); sqlci_DA.clear(); if (retval == -1) // EXIT command break; } if (packedEnd) { *packedEnd = packedEndC; packedStr = packedEnd; } else break; // terminate the unterminated stmt } else { // If unterminated quote, log it and history it and // display error message and exit the loop; // if just trailing blanks, it's no error, exit the loop. if (!fc_input_stmt->isEmpty(packedStr)) { if (is_single_stmt == DUNNO) { is_single_stmt = YES; stmt = fc_input_stmt; } else stmt = new InputStmt(fc_input_stmt, packedStr); stmt->logStmt(); sqlci_env->getSqlciStmts()->add(stmt); fc_input_stmt->syntaxErrorOnMissingQuote(packedStr); } break; } } while (*packedStr); } } if (is_single_stmt != YES) delete fc_input_stmt; } else { SqlciError(SQLCI_NO_STMT_MATCH, (ErrorParam *) 0); } #pragma nowarn(1506) // warning elimination return retval; #pragma warn(1506) // warning elimination } // end FixCommand::process
//////////////////////////////////////////////////////// // Returns: // 0, if string is fine, and semicolon-terminated // -1, invalid string // -2, eof (^Z or F6 on NT, ^D on Unix, ^Y on NSK) // -20, non-first-line interactive eof (used by FixCommand::process) // OR break (^C) // -99, error //////////////////////////////////////////////////////// Int32 InputStmt::readStmt(FILE * nonstdin, Int32 suppress_blank_line_output) { // char input_str[MAX_FRAGMENT_LEN+1]; char * input_str = new char[MAX_FRAGMENT_LEN+1]; Int32 prompt = sqlci_env->isInteractiveNow(); Int32 skip_first_fragment = 0; Int32 error = 0; StringFragment * prev_fragment = NULL; Int32 done = 0; //char buffer[256]; //SYSTEMTIME sysTime; // If called by FixCommand, with a partially completed statement, // blip past the get-first-line do-loop. if (first_fragment) { skip_first_fragment = 1; delete packed_string; packed_string = NULL; } else { // Get the first line, looping until we get a nonblank line do { Int32 eolSeenOrig = sqlci_env->eolSeenOnInput(); if ((prompt && eolSeenOrig && !(sqlci_env->sqlciRWEnv()->isSelectInProgress()) && !(sqlci_env->isMXCSMode())) || (sqlci_env->prevErrFlushInput() && !nonstdin)) { cout << ">>"; //cout << ">>" << endl; } if (prompt && eolSeenOrig && sqlci_env->sqlciRWEnv()->isSelectInProgress()) { cout << "S>"; } if (prompt && eolSeenOrig && sqlci_env->isMXCSMode()) { cout << "CS>"; } error = getLine(input_str, nonstdin, -1/*first line*/); sqlci_env->resetPrevErrFlushInput(); // Let NSK ESC be equivalent of NT ^Z or F6, i.e. EOF // (at least over a Telnet connection, // although unfortunately via OutsideView emulator). const char ESC = 27; // ASCII ESCAPE character switch (error) { case 1 : // no ";" seen yet, keep looking { // if this is an 'fc' or 'e' or 'exit' command, // don't require a terminating semicolon (';'). if ((! sqlci_env->isInteractiveNow()) || (input_str[0] == '\0')) break; // skip leading blanks UInt32 len = strlen(input_str); UInt32 i = 0; while ((i < len) && (input_str[i] == ' ')) { i++; } // 'i' cannot be equal to 'len', as that will make it a blank // line and we will not be in this 'case'. // if input string doesn't start with an 'e'(xit) or an 'f'(c), // break. It cannot be an exit or fc command. if ((input_str[i] != 'f') && (input_str[i] != 'F') && (input_str[i] != 'e') && (input_str[i] != 'E')) break; // find the next blank or end of line, whichever comes first. UInt32 k = i + 1; while ((k < len) && (input_str[k] != ' ')) k++; UInt32 cmdLen = k - i; char cmd[10]; // 4 is len of 'exit', non-semicolon terminating commands cant // be more than 4 chars in length. if (cmdLen > 4) break; // copy upshifted 'cmdLen' chars into 'cmd' buffer. UInt32 j = 0; for (j = 0; j < cmdLen; j++, i++) cmd[j] = (char)toupper(input_str[i]); cmd[j] = 0; if ((strcmp(cmd, "FC") == 0) || (strcmp(cmd, "E") == 0) || (strcmp(cmd, "EXIT") == 0)) { // found a non-semicolon terminating command. // If an 'E' is seen, change it to 'EXIT'. Sqlci // parser only recognizes an 'EXIT'. if (strcmp(cmd, "E") == 0) strcpy(input_str, "EXIT"); // Append a semicolon to this input. strcat(input_str, ";"); error = 0; } } break; case 0 : // normal input string case -4 : // statement followed immediately with eof break; case -1 : // bad string -- unmatched quote // call syntaxErrorOnMissingQuote() at end, after all frags saved break; case -2 : // eof (^Z) on first line of stmt (i.e. before the line) if (prompt) cout << endl; sqlci_env->setEol(-1); // Reset to initial eol state goto return_error; // return error; case -20 : // break (^C) on first line of stmt if (prompt) CLEAR_STDIN_EOF; sqlci_env->setEol(-1); // Reset to initial eol state // return error; goto return_error; // return error; case -3 : // error while reading input / obey file. { ErrorParam *p1 = new ErrorParam (errno); SqlciError (SQLCI_ERROR_READING_FILE, p1, (ErrorParam *) 0); delete p1; //return -99; error = -99; goto return_error; // return error; } case SqlciEnv::MAX_FRAGMENT_LEN_OVERFLOW : SqlciError (SQLCI_FRAGMENT_LEN_REACHED, (ErrorParam *) 0); // return error; goto return_error; // return error; default : // this case should never be reached { SqlciError (SQLCI_INTERNAL_ERROR, (ErrorParam *) 0); // return error; goto return_error; // return error; } } // Log an all-blank line here simply as a prompt; // also, if the input is not from terminal or // input is from an obey file, display the blank line on stdout // (logging and echoing of non-blank lines is done separately, in // SqlciEnv::executeCommands, Obey::process, // Repeat::process, FixCommand::process). // Except don't log trailing blanks in a multi-stmt line, e.g. // log "abc;def; " as "abc;" and "def;" but not the final "". if (input_str[0] == '\0' && !suppress_blank_line_output) if (eolSeenOrig || eolSeenOrig == sqlci_env->eolSeenOnInput()) { if (!prompt) cout << ">>" << endl; if (sqlci_env->get_logfile()->IsOpen()) sqlci_env->get_logfile()->Write (">>", 2); } } while (input_str[0] == '\0'); // ignore any number of whitespaces // followed by ";" or '\n' } do { if (skip_first_fragment) { // We already have (from FC) the first fragment(s). // No need to append an empty one and cause a blank line in history. skip_first_fragment = 0; prev_fragment = first_fragment; while (prev_fragment->next) prev_fragment = prev_fragment->next; error = 1; // getLine code for no semicolon seen } else { StringFragment * new_fragment = new StringFragment(); new_fragment->fragment = new char[strlen(input_str) + 1]; strcpy(new_fragment->fragment, input_str); new_fragment->next = 0; if (!first_fragment) first_fragment = new_fragment; else prev_fragment->next = new_fragment; prev_fragment = new_fragment; } if (error == 1) // no ";" seen yet, keep looking { if (prompt) cout << "+>"; error = getLine(input_str, nonstdin, 0/*not first line*/); // cerr << "##getLine: " << error << " " << cin.eof() << " " << prompt << endl; switch (error) { case 0 : // normal input string case 1 : // no ";" seen yet, keep looking case -4 : // end of file break; case -1 : // bad string -- unmatched quote // call syntaxErrorOnMissingQuote() at end, after all frags saved break; case -2 : // end of file // Reset to initial eol state sqlci_env->setEol(-1); // On a non-first line, EOF only means get back to the main // prompt without processing this command. It does not mean exit // from sqlci. So now make sure that this condition not treated // as session EOF, by clearing stdin and by returning a different // return code, signifying a "special" EOF (one to be logged and // historied, but not executed). if (prompt) { CLEAR_STDIN_EOF; error *= 10; // -20 } // return error; goto return_error; // return error; case -3 : // error while reading input / obey file. { ErrorParam *p1 = new ErrorParam (errno); SqlciError (SQLCI_ERROR_READING_FILE, p1, (ErrorParam *) 0); delete p1; error = -99; //return -99; goto return_error; // return error; } case SqlciEnv::MAX_FRAGMENT_LEN_OVERFLOW : SqlciError (SQLCI_FRAGMENT_LEN_REACHED, (ErrorParam *) 0); // return error; goto return_error; // return error; default : // this case should never be reached SqlciError (SQLCI_INTERNAL_ERROR, (ErrorParam *) 0); // return error; goto return_error; // return error; } } else done = -1; } while (!done); if (error == -1) // unmatched quote syntaxErrorOnMissingQuote(); return_error: if (input_str) delete [] input_str; return error; } // readStmt()
short Obey::process(SqlciEnv * sqlci_env) { short retcode = 0; enum ObeyState { SKIP_STMT, PROCESS_STMT, DONE }; if (sqlci_env->isOleServer()) { SqlciError (SQLCI_CMD_NOT_SUPPORTED, (ErrorParam *) 0 ); return 0; } char *name = get_argument(); errno = 0; FILE * file_stream = fopen(name, "r"); if (!file_stream) { #ifndef NA_CASE_INSENSITIVE_FILENAMES static Int32 desensitize = -1; if (desensitize < 0) { const char *env = getenv("SQL_MXCI_CASE_INSENSITIVE_OBEY"); if (!env || !*env || *env == '0') desensitize = 0; else if (*env == '1' || isupper(*env)) desensitize = 'U'; else if (isdigit(*env) || islower(*env)) desensitize = 'L'; else desensitize = 'U'; } if (desensitize) { NABoolean U = (desensitize == 'U'); for (Int32 i = 0; i < 2 && !file_stream; i++, U = !U) { if (U) #pragma nowarn(1506) // warning elimination {for (char *n=name; *n; n++) *n = toupper(*n);} #pragma warn(1506) // warning elimination else #pragma nowarn(1506) // warning elimination {for (char *n=name; *n; n++) *n = tolower(*n);} #pragma warn(1506) // warning elimination file_stream = fopen(name, "r"); } if (!file_stream) { // We've tried the original name aBc, // and ABC and abc, so as a last-ditch effort we try Abc. #pragma nowarn(1506) // warning elimination {for (char *n=name; *n; n++) *n = tolower(*n);} #pragma warn(1506) // warning elimination #pragma nowarn(1506) // warning elimination *name = toupper(*name); #pragma warn(1506) // warning elimination file_stream = fopen(name, "r"); // If all failed, ensure name all upper for prettier error msg if (!file_stream) #pragma nowarn(1506) // warning elimination {for (char *n=name; *n; n++) *n = toupper(*n);} #pragma warn(1506) // warning elimination } } if (!file_stream) #endif { ErrorParam *p1 = new ErrorParam (errno); ErrorParam *p2 = new ErrorParam (name); SqlciError (SQLCI_OBEY_FOPEN_ERROR, p1, p2, (ErrorParam *) 0 ); delete p1; delete p2; return 0; } } short prevEnvObey = sqlci_env->inObeyFile(); sqlci_env->setObey(-1); Int32 done = 0; Int32 ignore_toggle = 0; Int32 veryFirst = 1; ObeyState state; if (!section_name) state = PROCESS_STMT; else state = SKIP_STMT; Int32 section_was_seen = (state == PROCESS_STMT); InputStmt * input_stmt; SqlciNode * sqlci_node = 0; while (!done) { input_stmt = new InputStmt(sqlci_env); Int32 read_error = 0; if(veryFirst == 1) { veryFirst = 0; input_stmt->setVeryFirstLine(); } if (state != DONE) { // If section wasn't seen yet, then suppress echoing of blank lines // in the preceding sections of the obey file as we read thru it. read_error = input_stmt->readStmt(file_stream, !section_was_seen); if (feof(file_stream) || read_error == -99) { if (!section_was_seen && read_error != -99) { // Clear the DiagnosticsArea of any preceding sections' // syntax errors. sqlci_DA.clear(); SqlciError (SQLCI_SECTION_NOT_FOUND, new ErrorParam (section_name), new ErrorParam (name), (ErrorParam *) 0 ); } else if (!input_stmt->isEmpty() && read_error != -4) { // Unterminated statement in obey file. // Make the parser emit an error message. input_stmt->display((UInt16)0); //64bit project: add dummy arg - prevent C++ error input_stmt->logStmt(); input_stmt->syntaxErrorOnEof(); } state = DONE; } // if there is an eof directly after a statement // that is terminated with a semi-colon, process the // statement if (read_error == -4) state = PROCESS_STMT; } switch (state) { case SKIP_STMT: { if (input_stmt->sectionMatches(section_name)) { input_stmt->display((UInt16)0); //64bit project: add dummy arg - prevent C++ error state = PROCESS_STMT; section_was_seen = (state == PROCESS_STMT); // Clear the DiagnosticsArea for the section we're to process // (clear it of any preceding sections' syntax errors). sqlci_DA.clear(); } } break; case PROCESS_STMT: { #pragma nowarn(1506) // warning elimination short section_match = input_stmt->sectionMatches(); #pragma warn(1506) // warning elimination if (!section_name && section_match) { input_stmt->display((UInt16)0); //64bit project: add dummy arg - prevent C++ error if (sqlci_env->logCommands()) sqlci_env->get_logfile()->setNoLog(FALSE); input_stmt->logStmt(); if (sqlci_env->logCommands()) sqlci_env->get_logfile()->setNoLog(TRUE); break; } if ((!section_name) || (!section_match)) { input_stmt->display((UInt16)0); //64bit project: add dummy arg - prevent C++ error if (sqlci_env->logCommands()) sqlci_env->get_logfile()->setNoLog(FALSE); input_stmt->logStmt(); if (sqlci_env->logCommands()) sqlci_env->get_logfile()->setNoLog(TRUE); Int32 ignore_stmt = input_stmt->isIgnoreStmt(); if (ignore_stmt) ignore_toggle = ~ignore_toggle; if (ignore_stmt || ignore_toggle || input_stmt->ignoreJustThis()) { // ignore until stmt following the untoggling ?ignore sqlci_DA.clear(); } else { if (!read_error || read_error == -4) { #pragma nowarn(1506) // warning elimination retcode = sqlci_parser(input_stmt->getPackedString(), input_stmt->getPackedString(), &sqlci_node,sqlci_env); #pragma warn(1506) // warning elimination if (sqlci_node) { retcode = sqlci_node->process(sqlci_env); if (retcode == SQL_Canceled) { state = DONE; retcode = 0; } delete sqlci_node; } if (retcode > 0) { sqlci_env->setPrevErrFlushInput(); retcode = 0; } } } sqlci_env->displayDiagnostics() ; // Clear the DiagnosticsArea for the next command... sqlci_DA.clear(); // if an EXIT statement was seen, then a -1 will be returned // from process. We are done in that case. if (retcode == -1) { state = DONE; fclose(file_stream); done = -1; } } else { state = DONE; } } break; case DONE: { fclose(file_stream); done = -1; } break; default: { } break; } // switch on state // Delete the stmt if it's not one of those we saved on the history list if (!input_stmt->isInHistoryList()) delete input_stmt; if (breakReceived) { state = DONE; sqlci_env->resetPrevErrFlushInput(); retcode = 0; } } // while not done sqlci_env->setObey(prevEnvObey); return retcode; }