?? ipc.c
字號:
This function sends a line of text over the interprocesscommunication channel.*/Ipc_Status_t ipc_send_line (str) char *str; /* The text to send */{ int len; int send_len; char *s; Ipc_Status_t status; len = strlen(str); /* if short string, send it immediately */ if(len < 80) status = ipc_send_line_binary (str, len); else { /* otherwise, we have to send it as multiple strings */ /* because Mspice cannot handle things longer than 80 chars */ s = str; while(len > 0) { if(len < 80) send_len = len; else send_len = 79; status = ipc_send_line_binary (str, send_len); if(status != IPC_STATUS_OK) break; s += send_len; len -= send_len; } } return(status);}/*---------------------------------------------------------------------------*//*ipc_send_data_prefixThis function sends a ``>DATAB'' line over the interprocesscommunication channel to signal that this is the beginning of aresults dump for the current analysis point.*/Ipc_Status_t ipc_send_data_prefix (time) double time; /* The analysis point for this data set */{ char buffer[40]; sprintf (buffer, ">DATAB %.5E", time); return ipc_send_line (buffer);}/*---------------------------------------------------------------------------*//*ipc_send_data_suffixThis function sends a ``>ENDDATA'' line over the interprocesscommunication channel to signal that this is the end of a resultsdump from a particular analysis point.*/Ipc_Status_t ipc_send_data_suffix (){ Ipc_Status_t status; status = ipc_send_line (">ENDDATA"); if(status != IPC_STATUS_OK) return(status); return(ipc_flush());}/*---------------------------------------------------------------------------*//*ipc_send_dcop_prefixThis function sends a ``>DCOPB'' line over the interprocesscommunication channel to signal that this is the beginning of aresults dump from a DC operating point analysis.*/Ipc_Status_t ipc_send_dcop_prefix (){ return ipc_send_line (">DCOPB");}/*---------------------------------------------------------------------------*//*ipc_send_dcop_suffixThis function sends a ``>ENDDATA'' line over the interprocesscommunication channel to signal that this is the end of a resultsdump from a particular analysis point.*/Ipc_Status_t ipc_send_dcop_suffix (){ Ipc_Status_t status; status = ipc_send_line (">ENDDCOP"); if(status != IPC_STATUS_OK) return(status); return(ipc_flush());}/*---------------------------------------------------------------------------*//*ipc_send_evtdict_prefixThis function sends a ``>EVTDICT'' line over the interprocesscommunication channel to signal that this is the beginning of anevent-driven node dictionary.The line is sent only if the IPC is configuredfor UNIX sockets, indicating use with the V2 ATESSE SI process.*/Ipc_Status_t ipc_send_evtdict_prefix (){#ifdef IPC_AEGIS_MAILBOXES return IPC_STATUS_OK;#else return ipc_send_line (">EVTDICT");#endif}/*---------------------------------------------------------------------------*//*ipc_send_evtdict_suffixThis function sends a ``>ENDDICT'' line over the interprocesscommunication channel to signal that this is the end of anevent-driven node dictionary.The line is sent only if the IPC is configuredfor UNIX sockets, indicating use with the V2 ATESSE SI process.*/Ipc_Status_t ipc_send_evtdict_suffix (){#ifdef IPC_AEGIS_MAILBOXES return IPC_STATUS_OK;#else Ipc_Status_t status; status = ipc_send_line (">ENDDICT"); if(status != IPC_STATUS_OK) return(status); return(ipc_flush());#endif}/*---------------------------------------------------------------------------*//*ipc_send_evtdata_prefixThis function sends a ``>EVTDATA'' line over the interprocesscommunication channel to signal that this is the beginning of anevent-driven node data block.The line is sent only if the IPC is configuredfor UNIX sockets, indicating use with the V2 ATESSE SI process.*/Ipc_Status_t ipc_send_evtdata_prefix (){#ifdef IPC_AEGIS_MAILBOXES return IPC_STATUS_OK;#else return ipc_send_line (">EVTDATA");#endif}/*---------------------------------------------------------------------------*//*ipc_send_evtdata_suffixThis function sends a ``>ENDDATA'' line over the interprocesscommunication channel to signal that this is the end of anevent-driven node data block.The line is sent only if the IPC is configuredfor UNIX sockets, indicating use with the V2 ATESSE SI process.*/Ipc_Status_t ipc_send_evtdata_suffix (){#ifdef IPC_AEGIS_MAILBOXES return IPC_STATUS_OK;#else Ipc_Status_t status; status = ipc_send_line (">ENDDATA"); if(status != IPC_STATUS_OK) return(status); return(ipc_flush());#endif}/*---------------------------------------------------------------------------*//*ipc_send_errchkThis function sends a ``\ERRCHK [GO|NOGO]'' message over theinterprocess communication channel to signal that the initialparsing of the input deck has been completed and to indicatewhether or not errors were detected.*/Ipc_Status_t ipc_send_errchk(){ char str[IPC_MAX_LINE_LEN+1]; Ipc_Status_t status; if(g_ipc.errchk_sent) return(IPC_STATUS_OK); if(g_ipc.syntax_error) sprintf(str, "#ERRCHK NOGO"); else sprintf(str, "#ERRCHK GO"); g_ipc.errchk_sent = IPC_TRUE; status = ipc_send_line(str); if(status != IPC_STATUS_OK) return(status); return(ipc_flush());}/*---------------------------------------------------------------------------*//*ipc_send_endThis function sends either an ``>ENDANAL'' or an ``>ABORTED'' messageover the interprocess communication channel together with thetotal CPU time used to indicate whether or not the simulationcompleted normally.*/Ipc_Status_t ipc_send_end(){ char str[IPC_MAX_LINE_LEN+1]; Ipc_Status_t status; if(g_ipc.syntax_error || g_ipc.run_error) sprintf(str, ">ABORTED %.4f", g_ipc.cpu_time); else sprintf(str, ">ENDANAL %.4f", g_ipc.cpu_time); status = ipc_send_line(str); if(status != IPC_STATUS_OK) return(status); return(ipc_flush());}/*---------------------------------------------------------------------------*/static int stuff_binary_v1 (d1, d2, n, buf, pos) double d1, d2; /* doubles to be stuffed */ int n; /* how many of d1, d2 ( 1 <= n <= 2 ) */ char *buf; /* buffer to stuff to */ int pos; /* index at which to stuff */{ union { float float_val[2]; char ch[32]; } trick; int i, j; assert (protocol == IPC_PROTOCOL_V1); assert (sizeof(float) == 4); assert (sizeof(char) == 1); assert ((n >= 1) && (n <= 2)); trick.float_val[0] = d1; if (n > 1) { trick.float_val[1] = d2; } for (i = 0, j = pos; i < n*sizeof(float); j++, i++) buf[j] = trick.ch[i]; i = sizeof(float)*n + pos; buf[0] = 'A' + i - 1; return i;}/*---------------------------------------------------------------------------*//*ipc_send_doubleThis function sends a double data value over the interprocesscommunication channel preceded by a character string thatidentifies the simulation variable.*/Ipc_Status_t ipc_send_double (tag, value) char *tag; /* The node or instance */ double value; /* The data value to send */{ int i; int len; int fmt_buffer_len; switch (protocol) { case IPC_PROTOCOL_V1: strcpy (fmt_buffer, " "); /* save room for the length byte */ strcat (fmt_buffer, tag); strcat (fmt_buffer, " "); /* If talking to Mentor tools, must force upper case for Mspice 7.0 */ fmt_buffer_len = strlen(fmt_buffer); for(i = 0; i < fmt_buffer_len; i++) { if(islower(fmt_buffer[i])) fmt_buffer[i] = toupper(fmt_buffer[i]); } len = stuff_binary_v1 (value, 0.0, 1, fmt_buffer, strlen(fmt_buffer)); break; case IPC_PROTOCOL_V2: break; } return ipc_send_line_binary (fmt_buffer, len);}/*---------------------------------------------------------------------------*//*ipc_send_complexThis function sends a complex data value over the interprocesscommunication channel preceded by a character string thatidentifies the simulation variable.*/Ipc_Status_t ipc_send_complex (tag, value) char *tag; /* The node or instance */ Ipc_Complex_t value; /* The data value to send */{ int i; int len; int fmt_buffer_len; switch (protocol) { case IPC_PROTOCOL_V1: strcpy (fmt_buffer, " "); /* save room for the length byte */ strcat (fmt_buffer, tag); strcat (fmt_buffer, " "); /* If talking to Mentor tools, must force upper case for Mspice 7.0 */ fmt_buffer_len = strlen(fmt_buffer); for(i = 0; i < fmt_buffer_len; i++) { if(islower(fmt_buffer[i])) fmt_buffer[i] = toupper(fmt_buffer[i]); } len = stuff_binary_v1 (value.real, value.imag, 2, fmt_buffer, strlen(fmt_buffer)); break; case IPC_PROTOCOL_V2: break; } return ipc_send_line_binary (fmt_buffer, len);}/*---------------------------------------------------------------------------*//*ipc_send_eventThis function sends data from an event-driven node over the interprocesscommunication channel. The data is sent only if the IPC is configuredfor UNIX sockets, indicating use with the V2 ATESSE SI process.*/Ipc_Status_t ipc_send_event(ipc_index, step, plot_val, print_val, ipc_val, len) int ipc_index; /* Index used in EVTDICT */ double step; /* Analysis point or timestep (0.0 for DC) */ double plot_val; /* The value for plotting purposes */ char *print_val; /* The value for printing purposes */ void *ipc_val; /* The binary representation of the node data */ int len; /* The length of the binary representation */{#ifdef IPC_AEGIS_MAILBOXES return IPC_STATUS_OK;#else char buff[OUT_BUFFER_SIZE]; int i; int buff_len; char *buff_ptr; char *temp_ptr; float fvalue; /* Report error if size of data is too big for IPC channel block size */ if((len + strlen(print_val) + 100) >= OUT_BUFFER_SIZE) { printf("ERROR - Size of event-driven data too large for IPC channel\n"); return IPC_STATUS_ERROR; } /* Place the index into the buffer with a trailing space */ sprintf(buff, "%d ", ipc_index); assert(sizeof(float) == 4); assert(sizeof(int) == 4); /* Put the analysis step bytes in */ buff_len = strlen(buff); buff_ptr = buff + buff_len; fvalue = step; temp_ptr = (char *) &fvalue; for(i = 0; i < 4; i++) { *buff_ptr = temp_ptr[i]; buff_ptr++; buff_len++; } /* Put the plot value in */ fvalue = plot_val; temp_ptr = (char *) &fvalue; for(i = 0; i < 4; i++) { *buff_ptr = temp_ptr[i]; buff_ptr++; buff_len++; } /* Put the length of the binary representation in */ temp_ptr = (char *) &len; for(i = 0; i < 4; i++) { *buff_ptr = temp_ptr[i]; buff_ptr++; buff_len++; } /* Put the binary representation bytes in last */ temp_ptr = ipc_val; for(i = 0; i < len; i++) buff_ptr[i] = temp_ptr[i]; buff_ptr += len; buff_len += len; /* Put the print value in */ strcpy(buff_ptr, print_val); buff_ptr += strlen(print_val); buff_len += strlen(print_val); /* Send the data to the IPC channel */ return ipc_send_line_binary(buff, buff_len);#endif}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -