📄 par.c
字号:
if (version == blr_version4) csb->csb_g_flags |= csb_blr_version4;node = parse (tdbb, &csb, OTHER);csb->csb_node = node;if (*csb->csb_running++ != (UCHAR) blr_eoc) syntax_error (csb, "end_of_command");return csb;}SLONG PAR_symbol_to_gdscode ( SCHAR *name){/************************************** * * P A R _ s y m b o l _ t o _ g d s c o d e * ************************************** * * Functional description * Symbolic ASCII names are used in blr for posting and handling * exceptions. They are also used to identify error codes * within system triggers in a database. * * Returns the gds error status code for the given symbolic * name, or 0 if not found. * * Symbolic names may be null or space terminated. * **************************************/int i;int length;SCHAR *p;p = name;while (*p && *p != ' ') p++;length = p - name;for (i = 0; codes [i].code_number; i++) if (!strncmp (name, codes[i].code_string, length)) return codes [i].code_number;return 0;}static void error ( CSB csb, ...){/************************************** * * e r r o r * ************************************** * * Functional description * We've got a blr error other than a syntax error. Handle it. * **************************************/TDBB tdbb;STATUS *p;USHORT offset; int type;va_list args;/* Don't bother to pass tdbb for error handling */tdbb = GET_THREAD_DATA;VA_START (args, csb);csb->csb_running--;offset = csb->csb_running - csb->csb_blr;p = tdbb->tdbb_status_vector;*p++ = gds_arg_gds;*p++ = gds__invalid_blr;*p++ = gds_arg_number;*p++ = offset;*p++ = gds_arg_gds;*p++ = va_arg (args, STATUS);/* Pick up remaining args */while (*p++ = type = va_arg (args, int)) switch (type) { case gds_arg_gds: *p++ = (STATUS) va_arg (args, STATUS); break; case gds_arg_string: case gds_arg_interpreted: *p++ = (STATUS) va_arg (args, TEXT*); break; case gds_arg_cstring: *p++ = (STATUS) va_arg (args, int); *p++ = (STATUS) va_arg (args, TEXT*); break; case gds_arg_number: *p++ = (STATUS) va_arg (args, SLONG); break; default: assert (FALSE); case gds_arg_vms: case gds_arg_unix: case gds_arg_win32: case gds_arg_dos: case gds_arg_netware: case gds_arg_domain: case gds_arg_mpexl: *p++ = va_arg (args, int); break; }/* Give up whatever we were doing and return to the user. */ERR_punt();}static SSHORT find_proc_field ( PRC procedure, TEXT *name){/************************************** * * f i n d _ p r o c _ f i e l d * ************************************** * * Functional description * Look for named field in procedure output fields. * **************************************/VEC list;BLK *ptr, *end;PRM param;list = procedure->prc_output_fields;for (ptr = list->vec_object, end = ptr + list->vec_count - 1; ptr < end; ptr++) { param = (PRM) *ptr; if (!strcmp (name, param->prm_name)) return param->prm_number; }return -1;}static NOD par_args ( TDBB tdbb, CSB *csb, USHORT expected){/************************************** * * p a r _ a r g s * ************************************** * * Functional description * Parse a counted argument list. * **************************************/NOD node, *ptr;USHORT count;SET_TDBB (tdbb);count = BLR_BYTE;node = PAR_make_node (tdbb, count);node->nod_type = nod_list;ptr = node->nod_arg;if (count) do *ptr++ = parse (tdbb, csb, expected); while (--count);return node;}static NOD par_cast ( TDBB tdbb, CSB *csb){/************************************** * * p a r _ c a s t * ************************************** * * Functional description * Parse a datatype cast * **************************************/NOD node;FMT format;DSC *desc;SET_TDBB (tdbb);node = PAR_make_node (tdbb, e_cast_length);node->nod_count = count_table [blr_cast];format = (FMT) ALLOCDV (type_fmt, 1);format->fmt_count = 1;node->nod_arg [e_cast_fmt] = (NOD) format;desc = &format->fmt_desc[0];PAR_desc (csb, desc);format->fmt_length = desc->dsc_length;node->nod_arg [e_cast_source] = parse (tdbb, csb, VALUE);return node;}static XCP par_condition ( TDBB tdbb, CSB *csb){/************************************** * * p a r _ c o n d i t i o n * ************************************** * * Functional description * Parse an error conditions list. * **************************************/XCP exception_list;NOD dep_node;USHORT code_type;TEXT name[32], *p;SLONG code_number;SET_TDBB (tdbb);/* allocate a node to represent the conditions list */exception_list = (XCP) ALLOCDV (type_xcp, 1);exception_list->xcp_count = 1;code_type = BLR_BYTE;switch (code_type) { case blr_sql_code: exception_list->xcp_rpt[0].xcp_type = xcp_sql_code; exception_list->xcp_rpt[0].xcp_code = (SSHORT) BLR_WORD; break; case blr_gds_code: exception_list->xcp_rpt[0].xcp_type = xcp_gds_code; par_name (csb, name); for (p = name; *p; *p++) *p = LOWWER (*p); code_number = PAR_symbol_to_gdscode (name); if (code_number) exception_list->xcp_rpt[0].xcp_code = code_number; else error (*csb, gds__codnotdef, gds_arg_string, ERR_cstring (name), 0); break; case blr_exception: exception_list->xcp_rpt[0].xcp_type = xcp_xcp_code; par_name (csb, name); if ( !(exception_list->xcp_rpt[0].xcp_code = MET_lookup_exception_number (tdbb, name))) error (*csb, gds__xcpnotdef, gds_arg_string, ERR_cstring (name), 0); dep_node = PAR_make_node (tdbb, e_dep_length); dep_node->nod_type = nod_dependency; dep_node->nod_arg [e_dep_object] = (NOD) exception_list->xcp_rpt[0].xcp_code; dep_node->nod_arg [e_dep_object_type] = (NOD) obj_exception; LLS_PUSH (dep_node, &(*csb)->csb_dependencies); break; default: assert (FALSE); break; }return exception_list;}static XCP par_conditions ( TDBB tdbb, CSB *csb){/************************************** * * p a r _ c o n d i t i o n s * ************************************** * * Functional description * Parse an error conditions list. * **************************************/XCP exception_list;NOD dep_node;USHORT n, i, code_type;TEXT name[32], *p;SLONG code_number;SET_TDBB (tdbb);/* allocate a node to represent the conditions list */n = BLR_WORD;exception_list = (XCP) ALLOCDV (type_xcp, n);exception_list->xcp_count = n;for (i = 0; i < n; i++) { code_type = BLR_BYTE; switch (code_type) { case blr_sql_code: exception_list->xcp_rpt[i].xcp_type = xcp_sql_code; exception_list->xcp_rpt[i].xcp_code = (SSHORT) BLR_WORD; break; case blr_gds_code: exception_list->xcp_rpt[i].xcp_type = xcp_gds_code; par_name (csb, name); for (p = name; *p; *p++) *p = LOWWER (*p); code_number = PAR_symbol_to_gdscode (name); if (code_number) exception_list->xcp_rpt[i].xcp_code = code_number; else error (*csb, gds__codnotdef, gds_arg_string, ERR_cstring (name), 0); break; case blr_exception: exception_list->xcp_rpt[i].xcp_type = xcp_xcp_code; par_name (csb, name); if ( !(exception_list->xcp_rpt[i].xcp_code = MET_lookup_exception_number (tdbb, name))) error (*csb, gds__xcpnotdef, gds_arg_string, ERR_cstring (name), 0); dep_node = PAR_make_node (tdbb, e_dep_length); dep_node->nod_type = nod_dependency; dep_node->nod_arg [e_dep_object] = (NOD) exception_list->xcp_rpt[0].xcp_code; dep_node->nod_arg [e_dep_object_type] = (NOD) obj_exception; LLS_PUSH (dep_node, &(*csb)->csb_dependencies); break; case blr_default_code: exception_list->xcp_rpt[i].xcp_type = xcp_default; exception_list->xcp_rpt[i].xcp_code = 0; break; default: assert (FALSE); break; } }return exception_list;}static SSHORT par_context ( CSB *csb, SSHORT *context_ptr){/************************************** * * p a r _ c o n t e x t * ************************************** * * Functional description * Introduce a new context into the system. This involves * assigning a stream and possibly extending the compile * scratch block. * **************************************/SSHORT context, stream;struct csb_repeat *tail;stream = (*csb)->csb_n_stream++;context = (unsigned int) BLR_BYTE;CMP_csb_element (csb, stream);tail = CMP_csb_element (csb, context);if (tail->csb_flags & csb_used) error (*csb, gds__ctxinuse, 0);tail->csb_flags |= csb_used;tail->csb_stream = (UCHAR) stream;if (context_ptr) *context_ptr = context; return stream;}static void par_dependency ( TDBB tdbb, CSB *csb, SSHORT stream, SSHORT id, TEXT *field_name){/************************************** * * p a r _ d e p e n d e n c y * ************************************** * * Functional description * Register a field, relation, procedure or exception reference * as a dependency. * **************************************/NOD node, field_node;STR string;int length;SET_TDBB (tdbb);node = PAR_make_node (tdbb, e_dep_length);node->nod_type = nod_dependency;if ((*csb)->csb_rpt [stream].csb_relation) { node->nod_arg [e_dep_object] = (NOD) (*csb)->csb_rpt [stream].csb_relation; node->nod_arg [e_dep_object_type] = (NOD) obj_relation; }else if ((*csb)->csb_rpt [stream].csb_procedure) { node->nod_arg [e_dep_object] = (NOD) (*csb)->csb_rpt [stream].csb_procedure; node->nod_arg [e_dep_object_type] = (NOD) obj_procedure; }if (field_name) { node->nod_arg [e_dep_field] = field_node = PAR_make_node (tdbb, 1); field_node->nod_type = nod_literal; length = strlen (field_name); string = (STR) ALLOCDV (type_str, length); string->str_length = length; strcpy (string->str_data, field_name); field_node->nod_arg [0] = (NOD) string->str_data; }else if (id >= 0) { node->nod_arg [e_dep_field] = field_node = PAR_make_node (tdbb, 1); field_node->nod_type = nod_field; field_node->nod_arg [0] = (NOD) (SLONG) id; }LLS_PUSH (node, &(*csb)->csb_dependencies);}static NOD par_exec_proc ( TDBB tdbb, CSB *csb, SSHORT _operator){/************************************** * * p a r _ e x e c _ p r o c * ************************************** * * Functional description * Parse an execute procedure reference. * **************************************/NOD node, dep_node;PRC procedure;SET_TDBB (tdbb);procedure = NULL;{TEXT name [32];USHORT pid;if (_operator == blr_exec_pid) { pid = BLR_WORD; if (!(procedure = MET_lookup_procedure_id (tdbb, pid, FALSE, 0))) sprintf (name, "id %d", pid); }else { par_name (csb, name); procedure = MET_lookup_procedure (tdbb, name); }if (!procedure) error (*csb, gds__prcnotdef, gds_arg_string, ERR_cstring (name), 0);}node = PAR_make_node (tdbb, e_esp_length);node->nod_type = nod_exec_proc;node->nod_count = count_table [blr_exec_proc];node->nod_arg [e_esp_procedure] = (NOD) procedure;par_procedure_parms (tdbb, csb, procedure, &node->nod_arg [e_esp_in_msg], &node->nod_arg [e_esp_inputs], TRUE);par_procedure_parms (tdbb, csb, procedure, &node->nod_arg [e_esp_out_msg], &node->nod_arg [e_esp_outputs], FALSE);dep_node = PAR_make_node (tdbb, e_dep_length);dep_node->nod_type = nod_dependency;dep_node->nod_arg [e_dep_object] = (NOD) procedure;dep_node->nod_arg [e_dep_object_type] = (NOD) obj_procedure;LLS_PUSH (dep_node, &(*csb)->csb_dependencies);return node;}static NOD par_fetch ( TDBB tdbb, CSB *csb, NOD for_node){/************************************** * * p a r _ f e t c h * ************************************** * * Functional description * Parse a FETCH statement, and map it into * * FOR x IN relation WITH x.DBKEY EQ value ... * **************************************/RSE rse;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -