NAPA Compiler V4.50
Author: Yves Leduc, yves.leduc.be@gmail.com
Loading...
Searching...
No Matches
C:/Simulate/Napados/Source/lp.c File Reference
#include "./napa.h"
#include "./proto.h"

Go to the source code of this file.

Macros

#define EXTERN   extern
#define INSTRUCTION(x)
#define NOT_INSTRUCTION(x)

Functions

void line_parsing (void)
void check_version (const char *str)
char * get_node (char *str, char *nodnam, long *pseudo)
void get_var (char *str, const char *instruction)
void get_event (const char *str)
void get_post (char *str)
void get_header (char *str)
void get_directive (char *str1)
void get_nominal (char *str)
void get_decimate (char *str)
void get_interpolate (char *str)
void get_drop (char *str)
void get_command_line (char *str)
void get_update (char *str, const char *instruction)
void get_output (char *str)
void get_input (char *str)
void get_void (char *str)
void get_alias (char *str)
void get_terminate (char *str)
void get_synchronize (char *str)
void get_init (char *str)
void get_declare (char *str)
void get_assert (char *str)
void get_gateway (char *str)
void get_stuck (char *str)
void get_inject (char *str)
void get_call (char *str)
void get_restart (const char *str)
void get_debug (char *str)
void get_ping (char *str)
void get_comment (const char *str)
void get_fs_ts (char *str, long fs1ts0)
void get_sampling (char *str)
void get_interlude (char *str)
void get_random_seed (const char *str)
void get_title (char *str)
void get_export (const char *str)
void get_array (const char *variant, char *str)
void get_format (char *str)
void read_doub_format (char *str)
void read_int_format (char *str)
void read_hex_format (char *str)
void read_str_format (char *str)
void get_opcode (char *str)
void get_dump (char *str)
void get_load (char *str)
void get_data (char *str, const char *buffer, char *cell)
char * process_gen (char *str, long *pseudo, char *cell)
void process_cell (char *str, const char *nodnam, long *pseudo, char *cell)
long process_width (const char *brc, const char *tok, const char *instr)
void rearrange_data_interfaces (char *data_if, char *inst_if, const unsigned long *mlin, const unsigned long *mfil)
void record_cell_nam (const char *nam, long cur_depth, unsigned long *mlin, const unsigned long *mfil)
void record_file_nam (long d, const unsigned long *mlin, const unsigned long *mfil)
void inspect_short_form (const char *instruction, char *string, const char *tok)
void trap_unconsistencies (void)

Macro Definition Documentation

◆ EXTERN

#define EXTERN   extern

Definition at line 4 of file lp.c.

◆ INSTRUCTION

#define INSTRUCTION ( x)
Value:
(0 == strcmp(instruction, x))

Definition at line 73 of file lp.c.

Referenced by get_update(), get_var(), and line_parsing().

◆ NOT_INSTRUCTION

#define NOT_INSTRUCTION ( x)
Value:
(0 != strcmp(instruction, x))

Definition at line 74 of file lp.c.

Referenced by get_update(), and line_parsing().

Function Documentation

◆ check_version()

void check_version ( const char * str)

Definition at line 551 of file lp.c.

551 { /* Examples of versions V2.83a, X3.14 ... */
552 char ch;
553 char file_version[7] = {'\0'};
554 char napa_version[7] = {'\0'};
555 double file_version_id;
556 double napa_version_id;
557 (void) snprintf(file_version, (size_t) 6, "%s", str);
558 (void) snprintf(napa_version, (size_t) 6, "%s", NAPA_COMPILER_VERSION);
559 if (2 != sscanf(file_version, "%c%lf", &ch, &file_version_id)) { /* example 3.04 */
560 print_error_location("version", mline, mfile);
561 (void) fprintf(STDERR, "\n Version of file is not coded correctly\n");
562 (void) fprintf(STDERR, " file version: < %s > ?\n", str);
564 }
565 if (('V' != ch) && ('X' != ch)) {
566 print_error_location("version", mline, mfile);
567 (void) fprintf(STDERR, "\n Version of file is not coded correctly\n");
568 (void) fprintf(STDERR, " file version: < %s > ?\n", str);
570 }
571 if (2 != sscanf(napa_version, "%c%lf", &ch, &napa_version_id)) {
572 print_error_location("version", mline, mfile);
573 (void) fprintf(STDERR, "\n Version of NAPA compiler is not coded correctly\n");
574 (void) fprintf(STDERR, " NAPA version: < %s > ?\n", NAPA_COMPILER_VERSION);
576 }
577 if (('V' != ch) && ('X' != ch)) {
578 print_error_location("version", mline, mfile);
579 (void) fprintf(STDERR, "\n Version of NAPA compiler is not coded correctly\n");
580 (void) fprintf(STDERR, " NAPA version: < %s > ?\n", NAPA_COMPILER_VERSION);
582 }
583 if (file_version_id < napa_version_id) {
584 print_error_location("version", mline, mfile);
585 (void) fprintf(STDERR, "\n Version of file is older than current version of NAPA compiler\n");
586 (void) fprintf(STDERR, " file version: < %s >\n", str);
587 (void) fprintf(STDERR, " NAPA version: < %s >\n", NAPA_COMPILER_VERSION);
589 }
590 if (file_version_id > napa_version_id) {
591 print_warning_location("version", mline, mfile);
592 (void) fprintf(STDERR, "\n Version of file is newer than current version of NAPA compiler\n");
593 (void) fprintf(STDERR, " file version: < %s >\n", str);
594 (void) fprintf(STDERR, " NAPA version: < %s >\n\n", NAPA_COMPILER_VERSION);
595 }
596 return;
597}
void print_warning_location(const char *type, const unsigned long *mlin, const unsigned long *mfil)
Definition fc.c:1484
void print_error_location(const char *type, const unsigned long *mlin, const unsigned long *mfil)
Definition fc.c:1476
#define STDERR
Definition napa.h:105
#define NAPA_COMPILER_VERSION
Definition napa.h:30
void print_error_banner_and_exit(void)
Definition pr.c:5482

References NAPA_COMPILER_VERSION, print_error_banner_and_exit(), print_error_location(), print_warning_location(), and STDERR.

Referenced by line_parsing().

◆ get_alias()

void get_alias ( char * str)

Definition at line 2404 of file lp.c.

2404 {
2405
2406 /* INSTRUCTION: ALIAS */
2407 /* - alias_name alias_target */
2408
2409 char tok1[STRLENGTH] = {'\0'};
2410 char tok2[STRLENGTH] = {'\0'};
2411 char sgn[2] = {'\0'};
2412 long d, i;
2413
2414 if (data_flag[depth]) {
2415 print_error_location("data", mline, mfile);
2416 (void) fprintf(STDERR, " instruction 'alias' is not allowed in a data cell file\n");
2417 return;
2418 }
2419 if (0L != width) {
2420 print_warning_location("alias", mline, mfile);
2421 (void) fprintf(STDERR, " this instruction cannot be width limited\n");
2422 }
2423 str = get_sign_and_token(str, sgn, tok1); /* alias_name */
2424 if (0 == strcmp("(", tok1)) {
2425 print_error_location("alias", mline, mfile);
2426 (void) fprintf(STDERR, " no braces are expected around the alias identifier\n");
2427 return;
2428 }
2429 if (ISNOTEMPTY(sgn)) {
2430 print_error_location("alias", mline, mfile);
2431 (void) fprintf(STDERR, " no sign expected in front of the alias identifier <%s>\n", tok1);
2432 return;
2433 }
2434 if (!is_an_identifier(tok1)) {
2435 print_error_location("alias", mline, mfile);
2436 (void) fprintf(STDERR, " alias name <%s> is not a NAPA identifier\n", tok1);
2437 return;
2438 }
2439 if (ISEMPTY(tok1)) {
2440 print_error_location("alias", mline, mfile);
2441 (void) fprintf(STDERR, " alias name is missing\n");
2442 return;
2443 }
2444 i = alias_id(tok1);
2445 if (UNDEFINED != i) {
2446 print_error_location("alias", mline, mfile);
2447 (void) fprintf(STDERR, " duplicate alias definition, <%s> is already defined\n", tok1);
2448 print_location(Alias_List[i].mline, Alias_List[i].mfile);
2449 return;
2450 }
2451 i = node_id(tok1);
2452 if (UNDEFINED != i) {
2453 print_error_location("alias", mline, mfile);
2454 (void) fprintf(STDERR, " definition <%s> is colliding a node defined\n", tok1);
2455 print_location(Node_List[i].mline, Node_List[i].mfile);
2456 return;
2457 }
2458 i = var_id(tok1);
2459 if (UNDEFINED != i) {
2460 print_error_location("alias", mline, mfile);
2461 (void) fprintf(STDERR, " definition <%s> is colliding a variable defined\n", tok1);
2462 print_location(Var_List[i].mline, Var_List[i].mfile);
2463 return;
2464 }
2465 i = record_id(tok1);
2466 if (UNDEFINED != i) {
2467 print_error_location("alias", mline, mfile);
2468 (void) fprintf(STDERR, " definition <%s> is colliding a record defined\n", tok1);
2469 print_location(Record_List[i].mline, Record_List[i].mfile);
2470 return;
2471 }
2472 i = array_id(tok1);
2473 if (UNDEFINED != i) {
2474 print_error_location("alias", mline, mfile);
2475 (void) fprintf(STDERR, " definition <%s> is colliding an array defined\n", tok1);
2476 print_location(Array_List[i].mline, Array_List[i].mfile);
2477 return;
2478 }
2479 i = directive_id(tok1);
2480 if (UNDEFINED != i) {
2481 print_error_location("alias", mline, mfile);
2482 (void) fprintf(STDERR, " definition <%s> is colliding a directive defined\n", tok1);
2483 print_location(Directive_List[i].mline, Directive_List[i].mfile);
2484 return;
2485 }
2486 if (0 == strcmp(tok1, "fs")) { /* not catched by is_a_keyword() function */
2487 print_error_location("alias", mline, mfile);
2488 (void) fprintf(STDERR, " identifier cannot be the <fs> identifier\n");
2489 return;
2490 }
2491 i = is_a_keyword(tok1);
2492 if (ERROR == i) {
2493 print_error_location("alias", mline, mfile);
2494 (void) fprintf(STDERR, " keyword <%s> cannot be used as alias name\n", tok1);
2495 return;
2496 }
2497 if (WARNING == i) {
2498 print_warning_location("alias", mline, mfile);
2499 (void) fprintf(STDERR, " keyword <%s> is not recommended to be used as alias name\n", tok1);
2500 return;
2501 }
2502 if (ISEMPTY(str)) {
2503 print_error_location("alias", mline, mfile);
2504 (void) fprintf(STDERR, " alias target is missing\n");
2505 return;
2506 }
2507 str = get_sign_and_token(str, sgn, tok2); /* alias_target */
2508 if (!is_an_identifier(tok1)) {
2509 print_error_location("alias", mline, mfile);
2510 (void) fprintf(STDERR, " alias name <%s> is not a NAPA identifier\n", tok2);
2511 return;
2512 }
2513 if (ISNOTEMPTY(sgn)) {
2514 print_error_location("alias", mline, mfile);
2515 (void) fprintf(STDERR, " no sign expected in front of the alias target <%s>\n", tok2);
2516 }
2517 i = is_a_keyword(tok2);
2518 if ((ERROR == i) || (WARNING == i)) {
2519 print_error_location("alias", mline, mfile);
2520 (void) fprintf(STDERR, " a NAPA keyword cannot be an alias target: <%s>\n", tok2);
2521 return;
2522 }
2523 if (0 == strcmp(tok2, "Ground")) {
2524 print_error_location("alias", mline, mfile);
2525 (void) fprintf(STDERR, " node <Ground> cannot be an alias target\n");
2526 return;
2527 }
2528 if (0 == strcmp(tok2, "Zero")) {
2529 print_error_location("alias", mline, mfile);
2530 (void) fprintf(STDERR, " node <Zero> cannot be an alias target\n");
2531 return;
2532 }
2533 if (0 == strcmp(tok2, "One")) {
2534 print_error_location("alias", mline, mfile);
2535 (void) fprintf(STDERR, " node <One> cannot be an alias target\n");
2536 return;
2537 }
2538 if (0 == strcmp(tok2, "void")) {
2539 print_error_location("alias", mline, mfile);
2540 (void) fprintf(STDERR, " <void> cannot be an alias target\n");
2541 return;
2542 }
2543 if (1L <= LENGTH(str)) {
2544 print_error_location("alias", mline, mfile);
2545 (void) fprintf(STDERR, " too many parameters for this instruction <%s ?>\n", str);
2546 return;
2547 }
2548 strcpy_alloc(&(Alias_List[Num_Aliases].name), tok1, mline, mfile); /* alias name */
2549 strcpy_alloc(&(Alias_List[Num_Aliases].aliasof), tok2, mline, mfile); /* target name */
2550 for (d = 0L; d < MAXDEPTH; d++) {
2551 Alias_List[Num_Aliases].mline[d] = mline[d]; /* record line for identification */
2552 Alias_List[Num_Aliases].mfile[d] = mfile[d]; /* record file for identification */
2553 }
2554 increment_alias_number("alias");
2555 return;
2556}
void print_location(const unsigned long *mlin, const unsigned long *mfil)
Definition fc.c:1510
long alias_id(const char *identifier)
Definition id.c:624
void increment_alias_number(const char *kind)
Definition id.c:150
void strcpy_alloc(char **dest, const char *sour, const unsigned long *mlin, const unsigned long *mfil)
Definition id.c:114
long array_id(const char *identifier)
Definition id.c:635
long directive_id(const char *identifier)
Definition id.c:707
int is_a_keyword(const char *identifier)
Definition id.c:1527
long node_id(const char *identifier)
Definition id.c:718
long var_id(const char *identifier)
Definition id.c:855
long record_id(const char *identifier)
Definition id.c:796
#define MAXDEPTH
Definition napa.h:212
EXTERN long Num_Aliases
Definition napa.h:799
EXTERN VAR_TYPE Var_List[2047L]
Definition napa.h:970
EXTERN RECORD_TYPE Record_List[127L]
Definition napa.h:965
EXTERN ARRAY_TYPE Array_List[63L]
Definition napa.h:950
#define LENGTH(s)
Definition napa.h:397
#define UNDEFINED
Definition napa.h:331
EXTERN NODE_TYPE Node_List[4095L]
Definition napa.h:962
#define WARNING
Definition napa.h:409
EXTERN ALIAS_TYPE Alias_List[127L]
Definition napa.h:949
EXTERN DIRECTIVE_TYPE Directive_List[255L]
Definition napa.h:955
#define ERROR
Definition napa.h:410
#define ISNOTEMPTY(s)
Definition napa.h:395
#define STRLENGTH
Definition napa.h:217
#define ISEMPTY(s)
Definition napa.h:394
int is_an_identifier(const char *tok)
Definition tk.c:1327
char * get_sign_and_token(char *str, char *sgn, char *tok)
Definition tk.c:1188

References alias_id(), Alias_List, array_id(), Array_List, directive_id(), Directive_List, ERROR, get_sign_and_token(), increment_alias_number(), is_a_keyword(), is_an_identifier(), ISEMPTY, ISNOTEMPTY, LENGTH, MAXDEPTH, node_id(), Node_List, Num_Aliases, print_error_location(), print_location(), print_warning_location(), record_id(), Record_List, STDERR, strcpy_alloc(), STRLENGTH, UNDEFINED, var_id(), Var_List, and WARNING.

Referenced by line_parsing().

◆ get_array()

void get_array ( const char * variant,
char * str )

Definition at line 3695 of file lp.c.

3695 {
3696
3697 /* INSTRUCTION: ARRAY */
3698 /* - qualifier (...) */
3699 /* - node name mandatory */
3700 /* - size mandatory [number] or [] */
3701 /* - either: input file name optional */
3702 /* either: list of variables (for pointer kind) mandatory */
3703
3704 char tok1[STRLENGTH] = {'\0'};
3705 char tok2[STRLENGTH] = {'\0'};
3706 char tok3[STRLENGTH] = {'\0'};
3707 char tok4[STRLENGTH] = {'\0'};
3708 char tok5[STRLENGTH] = {'\0'};
3709 char tok6[STRLENGTH] = {'\0'};
3710 char brc[3] = {'\0'};
3711 long size;
3712 long type;
3713 long i, d, v;
3714 char *s = (char*) NULL;
3715 if (0 == strcmp(variant, "array")) {
3716 str = get_token(str, tok2, false); /* "(" */
3717 str = get_token(str, tok3, false); /* "analog" or ... */
3718 str = get_token(str, tok4, false); /* ")" */
3719 } else {
3720 (void) strcpy(tok2, "(");
3721 (void) strcpy(tok3, "pointer");
3722 (void) strcpy(tok4, ")");
3723 }
3724 (void) snprintf(tok1, (size_t) (STRLENGTH-1L), "%s%s%s", tok2, tok3, tok4); /* tok1: qualifier (...) */
3725 str = get_token(str, tok2, false); /* tok2: array name */
3726 if (!is_an_identifier(tok2)) {
3727 print_error_location(variant, mline, mfile);
3728 (void) fprintf(STDERR, " %s name <%s> is not a NAPA identifier\n", variant, tok2);
3729 /* parsing of instruction may continue */
3730 return;
3731 }
3732 if (0L != width) {
3733 print_error_location(variant, mline, mfile);
3734 (void) fprintf(STDERR, " %s <%s> cannot be width limited\n", variant, tok2);
3735 /* parsing of instruction may continue */
3736 }
3737 if (ISEMPTY(tok2)) {
3738 print_error_location(variant, mline, mfile);
3739 (void) fprintf(STDERR, " %s name is missing\n", variant);
3740 /* parsing of instruction may continue */
3741 return;
3742 }
3743 i = record_id(tok2);
3744 if (UNDEFINED != i) {
3745 print_error_location("record", mline, mfile);
3746 (void) fprintf(STDERR, " duplicate record definition, <%s> is already defined\n", tok2);
3747 print_location(Record_List[i].mline, Record_List[i].mfile);
3748 /* parsing of instruction may continue */
3749 return;
3750 }
3751 i = array_id(tok2);
3752 if (UNDEFINED != i) {
3753 print_error_location(variant, mline, mfile);
3754 (void) fprintf(STDERR, " definition <%s> is colliding an array defined\n", tok2);
3755 print_location(Array_List[i].mline, Array_List[i].mfile);
3756 /* parsing of instruction may continue */
3757 return;
3758 }
3759 i = alias_id(tok2);
3760 if (UNDEFINED != i) {
3761 print_error_location(variant, mline, mfile);
3762 (void) fprintf(STDERR, " definition <%s> is colliding an alias defined\n", tok2);
3763 print_location(Alias_List[i].mline, Alias_List[i].mfile);
3764 /* parsing of instruction may continue */
3765 }
3766 i = var_id(tok2);
3767 if (UNDEFINED != i) {
3768 print_error_location(variant, mline, mfile);
3769 (void) fprintf(STDERR, " definition <%s> is colliding a variable defined\n", tok2);
3770 print_location(Var_List[i].mline, Var_List[i].mfile);
3771 /* parsing of instruction may continue */
3772 return;
3773 }
3774 i = node_id(tok2);
3775 if (UNDEFINED != i) {
3776 print_error_location(variant, mline, mfile);
3777 (void) fprintf(STDERR, " definition <%s> is colliding a node defined\n", tok2);
3778 print_location(Node_List[i].mline, Node_List[i].mfile);
3779 /* parsing of instruction may continue */
3780 return;
3781 }
3782 i = directive_id(tok2);
3783 if (UNDEFINED != i) {
3784 print_error_location(variant, mline, mfile);
3785 (void) fprintf(STDERR, " definition <%s> is colliding a directive defined\n", tok2);
3786 print_location(Node_List[i].mline, Node_List[i].mfile);
3787 /* parsing of instruction may continue */
3788 return;
3789 }
3790 str = get_token_between_braces(str, brc, tok6); /* size */
3791 if (0 != strcmp(brc, "[]")) {
3792 print_error_location(variant, mline, mfile);
3793 (void) fprintf(STDERR, " size is not properly declared\n");
3794 /* parsing of instruction may continue */
3795 return;
3796 }
3797 s = tok6;
3798 s = get_token(s, tok3, false); /* tok3: size */
3799 if (ISEMPTY(tok3)) {
3800 (void) strcpy(tok3, "0");
3801 }
3802 if (ISEMPTY(brc)) {
3803 print_error_location(variant, mline, mfile);
3804 (void) fprintf(STDERR, " <%s> is not properly declared as an array\n", tok2);
3805 process_array_error(tok2);
3806 /* parsing of instruction may continue */
3807 return;
3808 }
3809 (void) strcpy(tok6, str);
3810 if (0 == strcmp(tok1, "(analog)" )) {
3811 type = ANALOG_DATA_TYPE;
3812 } else if (0 == strcmp(tok1, "(digital)")) {
3813 type = DIGITAL_DATA_TYPE;
3814 } else if (0 == strcmp(tok1, "(hex)" )) {
3815 type = HEX_DATA_TYPE;
3816 } else if (0 == strcmp(tok1, "(pointer)")) {
3817 type = UNKNOWN_TYPE;
3818 } else {
3819 print_error_location(variant, mline, mfile);
3820 (void) fprintf(STDERR, " (%s) is not a correct type qualifier\n", tok1);
3821 (void) fprintf(STDERR, " valid qualifiers are:\n");
3822 (void) fprintf(STDERR, " (digital) (hex)\n");
3823 (void) fprintf(STDERR, " (analog)\n");
3824 (void) fprintf(STDERR, " (pointer)\n");
3825 return;
3826 }
3827
3828 if ((ANALOG_DATA_TYPE == type) || (DIGITAL_DATA_TYPE == type) || (HEX_DATA_TYPE == type)) {
3829
3830 /* RAM and ROM Arrays of integer or double */
3831
3832 str = get_token_between_braces(str, brc, tok4); /* tok4: optional file name */
3833 if ((0 != strcmp(brc, "\"\"")) && ISNOTEMPTY(str)) {
3834 str = get_token(str, tok5, false);
3835 v = var_id(tok5);
3836 if ((UNDEFINED == v) || (STRING_DATA_TYPE != Var_List[v].type)) {
3837 print_error_location("array of numbers", mline, mfile);
3838 (void) fprintf(STDERR, " <%s> is not a string variable\n", tok5);
3840 /* parsing of instruction may continue */
3841 return;
3842 }
3843 (void) get_token(Var_List[v].value, tok4, false); /* use variable value as input */
3844 (void) snprintf(tok6, (size_t) (STRLENGTH-1L), "\"%s\"", tok4);
3845 }
3846 resolve_pathnames(tok6, depth); /* resolve pathname using conventions */
3847 (void) get_token_between_braces(tok6, brc, tok4);
3848 strcpy_alloc(&(Array_List[Num_Arrays].variant), variant, mline, mfile); /* variant_name */
3849 strcpy_alloc(&(Array_List[Num_Arrays].size), tok3, mline, mfile); /* size_name */
3850 strcpy_alloc(&(Array_List[Num_Arrays].name), tok2, mline, mfile); /* array_name */
3851 strcpy_alloc(&(Array_List[Num_Arrays].fname), tok4, mline, mfile); /* File or '\0' */
3852 Array_List[Num_Arrays].port = 0L; /* number of ports of the memory */
3853 Array_List[Num_Arrays].kind = UNKNOWN_KIND; /* usage is not yet known */
3854 Array_List[Num_Arrays].type = type; /* array type */
3855 Array_List[Num_Arrays].used = false; /* not yet verified as used */
3856 for (d = 0L; d < MAXDEPTH; d++) {
3857 Array_List[Num_Arrays].mline[d] = mline[d]; /* record line for identification */
3858 Array_List[Num_Arrays].mfile[d] = mfile[d]; /* record file for identification */
3859 }
3860 increment_array_number(variant);
3861
3862 } else {
3863
3864 /* Arrays of POINTERS */
3865
3866 Pointer_Flag = true;
3867 if (1 != sscanf(tok3, "%li", &size)) {
3868 print_error_location(variant, mline, mfile);
3869 (void) fprintf(STDERR, " size is not a well-formed positive C integer <%s>\n", tok3);
3870 size = 0L;
3871 /* parsing of instruction may continue */
3872 return;
3873 }
3874 if (0L > size) {
3875 print_error_location(variant, mline, mfile);
3876 (void) fprintf(STDERR, " size is not positive <%ld>\n", size);
3877 size = 0L;
3878 /* parsing of instruction may continue */
3879 return;
3880 }
3881 if (((char*) NULL != strstr(str, " ::")) || ((char*) NULL != strstr(str, ":: "))) {
3882 print_error_location(variant, mline, mfile);
3883 (void) fprintf(STDERR, " no space is allowed around the operator '::'\n" );
3884 /* parsing of instruction may continue */
3885 }
3886 strcpy_alloc(&(Record_List[Num_Records].name), tok2, mline, mfile); /* array_name */
3887 strcpy_alloc(&(Record_List[Num_Records].list1), str, mline, mfile); /* list of parameters */
3888 strcpy_alloc(&(Record_List[Num_Records].list2), str, mline, mfile); /* list of parameters */
3889 Record_List[Num_Records].size = size; /* size of the array */
3890 Record_List[Num_Records].nrow = 1L; /* number of rows */
3891 Record_List[Num_Records].ncol = size; /* number of cols */
3892 Record_List[Num_Records].used = false; /* not yet verified as used */
3893 Record_List[Num_Records].determined = false; /* not yet determined */
3894 Record_List[Num_Records].nflag = false; /* ganging by name */
3895 Record_List[Num_Records].pflag = false; /* ganging by position */
3896 Record_List[Num_Records].ID = Num_Records; /* unique array ID */
3897 for (d = 0L; d < MAXDEPTH; d++) {
3898 Record_List[Num_Records].mline[d] = mline[d]; /* record line for identification */
3899 Record_List[Num_Records].mfile[d] = mfile[d]; /* record file for identification */
3900 }
3901 increment_record_number(variant);
3902 }
3903 return;
3904}
void increment_array_number(const char *kind)
Definition id.c:163
void increment_record_number(const char *kind)
Definition id.c:453
void process_array_error(const char *tok1)
Definition mp.c:441
void process_variable_error(const char *tok1)
Definition mp.c:331
#define UNKNOWN_TYPE
Definition napa.h:332
EXTERN long Num_Records
Definition napa.h:828
EXTERN long Num_Arrays
Definition napa.h:800
#define ANALOG_DATA_TYPE
Definition napa.h:338
EXTERN int Pointer_Flag
Definition napa.h:875
#define STRING_DATA_TYPE
Definition napa.h:339
#define HEX_DATA_TYPE
Definition napa.h:340
#define UNKNOWN_KIND
Definition napa.h:224
#define DIGITAL_DATA_TYPE
Definition napa.h:337
char * get_token(char *str, char *tok, long keep_quotes)
Definition tk.c:1210
char * get_token_between_braces(char *str, char *brc, char *tok)
Definition tk.c:1110
void resolve_pathnames(char *lin, long d)
Definition tk.c:265

References alias_id(), Alias_List, ANALOG_DATA_TYPE, array_id(), Array_List, DIGITAL_DATA_TYPE, directive_id(), get_token(), get_token_between_braces(), HEX_DATA_TYPE, increment_array_number(), increment_record_number(), is_an_identifier(), ISEMPTY, ISNOTEMPTY, MAXDEPTH, node_id(), Node_List, Num_Arrays, Num_Records, Pointer_Flag, print_error_location(), print_location(), process_array_error(), process_variable_error(), record_id(), Record_List, resolve_pathnames(), STDERR, strcpy_alloc(), STRING_DATA_TYPE, STRLENGTH, UNDEFINED, UNKNOWN_KIND, UNKNOWN_TYPE, var_id(), and Var_List.

Referenced by line_parsing().

◆ get_assert()

void get_assert ( char * str)

Definition at line 2804 of file lp.c.

2804 {
2805
2806 /* INSTRUCTION: ASSERT */
2807 /* - C conditional expression mandatory */
2808
2809 /* Conditional expression is stored for further processing */
2810
2811 char tok1[STRLENGTH] = {'\0'};
2812 char buf[STRLENGTH] = {'\0'};
2813 char brc[3] = {'\0'};
2814 char *s = (char*) NULL;
2815 long d;
2816 if (0L != width) {
2817 print_warning_location("assert", mline, mfile);
2818 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width);
2819 }
2820 if (ISEMPTY(str)) {
2821 print_error_location("assert", mline, mfile);
2822 (void) fprintf(STDERR, " assert message and conditional expression is missing\n");
2823 return;
2824 }
2825 (void) snprintf(buf, (size_t) 31, "$assert$_%ld", Num_Asserts);
2826 increment_assert_number("assert");
2827 resolve_pathnames(tok1, depth); /* resolve pathname using conventions */
2828 strcpy_alloc(&(Update_List[Num_Updates].name), buf, mline, mfile); /* keyword $assert$_.. */
2829 clean_parentheses(str);
2830 strcpy_alloc(&(Update_List[Num_Updates].value), str, mline, mfile); /* unprocessed */
2831 s = str;
2832 str = get_token_between_braces(str, brc, tok1);
2833 if (ISEMPTY(tok1)) {
2834 print_error_location("assert", mline, mfile);
2835 (void) fprintf(STDERR, " assert message is missing\n");
2836 return;
2837 }
2838 if (0 != strcmp(brc, "\"\"")) {
2839 print_error_location("assert", mline, mfile);
2840 (void) fprintf(STDERR, " double quotes are missing around assert message <%s>\n", s);
2841 return;
2842 }
2843 C_syntax_checker(str, mline, mfile);
2844 Update_List[Num_Updates].ID = Num_Updates; /* unique update variable ID */
2845 Update_List[Num_Updates].determined = false; /* not yet determined */
2846 Update_List[Num_Updates].event = false; /* not an event variable */
2847 Update_List[Num_Updates].constant = false; /* by default */
2848 Update_List[Num_Updates].segment = Num_Segments - 1L; /* record segment level */
2849 Segment_List[Num_Segments-1L].used1 = true;
2850 for (d = 0L; d < MAXDEPTH; d++) {
2851 Update_List[Num_Updates].mline[d] = mline[d]; /* record line for identification */
2852 Update_List[Num_Updates].mfile[d] = mfile[d]; /* record file for identification */
2853 }
2854 increment_update_number("assert");
2855 Assert_Flag = true;
2856 return;
2857}
void increment_assert_number(const char *kind)
Definition id.c:176
void increment_update_number(const char *kind)
Definition id.c:518
EXTERN long Num_Updates
Definition napa.h:834
EXTERN long Num_Asserts
Definition napa.h:801
EXTERN long Num_Segments
Definition napa.h:831
EXTERN SEGMENT_TYPE Segment_List[127L]
Definition napa.h:966
EXTERN int Assert_Flag
Definition napa.h:844
EXTERN UPDATE_TYPE Update_List[2047L]
Definition napa.h:968
void clean_parentheses(char *tok)
Definition tk.c:403
void C_syntax_checker(char *str, const unsigned long *mlin, const unsigned long *mfil)
Definition sx.c:1896

References Assert_Flag, C_syntax_checker(), clean_parentheses(), get_token_between_braces(), increment_assert_number(), increment_update_number(), ISEMPTY, MAXDEPTH, Num_Asserts, Num_Segments, Num_Updates, print_error_location(), print_warning_location(), resolve_pathnames(), Segment_List, STDERR, strcpy_alloc(), STRLENGTH, and Update_List.

Referenced by line_parsing().

◆ get_call()

void get_call ( char * str)

Definition at line 3039 of file lp.c.

3039 {
3040
3041 /* INSTRUCTION: CALL */
3042 /* - parameters mandatory */
3043
3044 /* Parameters are stored for further processing */
3045
3046 long d;
3047 char buf[STRLENGTH] = {'\0'};
3048
3049 Call_Flag = true;
3050 Update_Flag = true;
3051 if (data_flag[depth]) {
3052 print_error_location("data", mline, mfile);
3053 (void) fprintf(STDERR, " instruction 'call' is not allowed in a data cell file\n");
3054 return;
3055 }
3056 if (0L != width) {
3057 print_error_location("call", mline, mfile);
3058 (void) fprintf(STDERR, " C expression cannot be width limited\n");
3059 /* parsing of instruction may continue */
3060 }
3061 if (ISEMPTY(str)) {
3062 print_error_location("call", mline, mfile);
3063 (void) fprintf(STDERR, " call expression is missing\n");
3064 return;
3065 }
3066 (void) snprintf(buf, (size_t) 31, "$call$_%ld", Num_Calls);
3067 increment_call_number("call");
3068 strcpy_alloc(&(Update_List[Num_Updates].name), buf, mline, mfile); /* keyword $call$_.. */
3069 resolve_pathnames(str, depth); /* resolve pathname using conventions */
3070 strcpy_alloc(&(Update_List[Num_Updates].value), str, mline, mfile); /* unprocessed */
3071 Update_List[Num_Updates].ID = Num_Updates; /* unique update variable ID */
3072 Update_List[Num_Updates].determined = false; /* not yet determined */
3073 Update_List[Num_Updates].event = false; /* not an event variable */
3074 Update_List[Num_Updates].constant = false; /* by default */
3075 Update_List[Num_Updates].segment = Num_Segments - 1L; /* record segment level */
3076 Segment_List[Num_Segments-1L].used1 = true;
3077 for (d = 0L; d < MAXDEPTH; d++) {
3078 Update_List[Num_Updates].mline[d] = mline[d]; /* record line for identification */
3079 Update_List[Num_Updates].mfile[d] = mfile[d]; /* record file for identification */
3080 }
3082 return;
3083}
void increment_call_number(const char *kind)
Definition id.c:189
EXTERN long Num_Calls
Definition napa.h:802
EXTERN int Update_Flag
Definition napa.h:886
EXTERN int Call_Flag
Definition napa.h:845

References Call_Flag, increment_call_number(), increment_update_number(), ISEMPTY, MAXDEPTH, Num_Calls, Num_Segments, Num_Updates, print_error_location(), resolve_pathnames(), Segment_List, STDERR, strcpy_alloc(), STRLENGTH, Update_Flag, and Update_List.

Referenced by line_parsing().

◆ get_command_line()

void get_command_line ( char * str)

Definition at line 2069 of file lp.c.

2069 {
2070
2071 /* INSTRUCTION: COMMAND LINE */
2072 /* - list of parameters mandatory */
2073
2074 char tok[STRLENGTH] = {'\0'};
2075 char sgn[2] = {'\0'};
2076 long d, i;
2077
2078 if (0L != width) {
2079 print_warning_location("command_line", mline, mfile);
2080 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width);
2081 }
2082 if (ISEMPTY(str)) {
2083 strcpy_alloc(&(Cmdline_List[Num_Cmdlines].parms), "void", mline, mfile);
2084 strcpy_alloc(&(Cmdline_List[Num_Cmdlines].comment), "", mline, mfile);
2085 for (d = 0L; d < MAXDEPTH; d++) {
2086 Cmdline_List[Num_Cmdlines].mline[d] = mline[d]; /* record line for identification */
2087 Cmdline_List[Num_Cmdlines].mfile[d] = mfile[d]; /* record file for identification */
2088 }
2089 increment_cmdline_number("command_line");
2090 Cmdline_Flag = true;
2091 return;
2092 }
2093
2094 while (ISNOTEMPTY(str)) {
2095 str = get_sign_and_token(str, sgn, tok);
2096 if (ISNOTEMPTY(sgn)) {
2097 print_error_location("command_line", mline, mfile);
2098 (void) fprintf(STDERR, " no sign expected in front of a command_line parameter <%s>\n", tok);
2099 /* parsing of instruction may continue */
2100 }
2101 i = cmdline_id(tok);
2102 if ((UNDEFINED != i) && (0 != strcmp(tok, "void"))) {
2103 print_error_location("command_line", mline, mfile);
2104 (void) fprintf(STDERR, " duplication of command_line parameter <%s>\n", tok);
2105 print_location(Cmdline_List[i].mline, Cmdline_List[i].mfile);
2106 /* parsing of instruction may continue */
2107 return;
2108 }
2109 if (!is_an_identifier(tok)) {
2110 print_error_location("command_line", mline, mfile);
2111 (void) fprintf(STDERR, " parameter <%s> is not a NAPA identifier\n", tok);
2112 }
2113 strcpy_alloc(&(Cmdline_List[Num_Cmdlines].parms), tok, mline, mfile);
2114 strcpy_alloc(&(Cmdline_List[Num_Cmdlines].comment), "", mline, mfile); /* filled later */
2115 for (d = 0L; d < MAXDEPTH; d++) {
2116 Cmdline_List[Num_Cmdlines].mline[d] = mline[d]; /* record line for identification */
2117 Cmdline_List[Num_Cmdlines].mfile[d] = mfile[d]; /* record file for identification */
2118 }
2119 increment_cmdline_number("command_line");
2120 Cmdline_Flag = true;
2121 }
2122 return;
2123}
long cmdline_id(const char *identifier)
Definition id.c:657
void increment_cmdline_number(const char *kind)
Definition id.c:202
EXTERN int Cmdline_Flag
Definition napa.h:846
EXTERN CMDLINE_TYPE Cmdline_List[63L]
Definition napa.h:951
EXTERN long Num_Cmdlines
Definition napa.h:804

References Cmdline_Flag, cmdline_id(), Cmdline_List, get_sign_and_token(), increment_cmdline_number(), is_an_identifier(), ISEMPTY, ISNOTEMPTY, MAXDEPTH, Num_Cmdlines, print_error_location(), print_location(), print_warning_location(), STDERR, strcpy_alloc(), STRLENGTH, and UNDEFINED.

Referenced by line_parsing().

◆ get_comment()

void get_comment ( const char * str)

Definition at line 3254 of file lp.c.

3254 {
3255
3256 /* INSTRUCTION: COMMENT */
3257 /* - comment "a_string" */
3258
3259 long i, j;
3260 char buffer[LINLENGTH] = {'\0'};
3261 if (ISNOTEMPTY(str)) {
3262 Comment_Flag = true;
3263 }
3264 j = 0L;
3265 if ('"' != str[0]) { /* test first character and skip it */
3266 print_error_location("comment", mline, mfile);
3267 (void) fprintf(STDERR, " parameter is not a well-formed string\n");
3269 }
3270 for (i = 1L; i < LINLENGTH; i++) { /* copy with special process of escape character */
3271 if ('\0' == str[i]) {
3272 if ('"' != str[i-1]) {
3273 print_error_location("comment", mline, mfile);
3274 (void) fprintf(STDERR, " parameter is not a well formed string\n");
3276 }
3277 break;
3278 }
3279 if ('\\' == str[i]) {
3280 buffer[j] = '|'; /* no escape character in a comment, replace by '|' */
3281 } else {
3282 buffer[j] = str[i];
3283 }
3284 j++;
3285 }
3286 buffer[j-1L] = '\0'; /* skip last " character */
3287 (void) snprintf(Comment_String[Num_Comments], (size_t) (LINLENGTH-1L), "%s", buffer);
3289 return;
3290}
void increment_comment_number(const char *kind)
Definition id.c:215
#define LINLENGTH
Definition napa.h:216
EXTERN char Comment_String[63L][16383L]
Definition napa.h:925
EXTERN int Comment_Flag
Definition napa.h:847
EXTERN long Num_Comments
Definition napa.h:805

References Comment_Flag, Comment_String, increment_comment_number(), ISNOTEMPTY, LINLENGTH, Num_Comments, print_error_banner_and_exit(), print_error_location(), and STDERR.

Referenced by line_parsing().

◆ get_data()

void get_data ( char * str,
const char * buffer,
char * cell )

Definition at line 4309 of file lp.c.

4309 {
4310
4311 /* DATA PROCESSING */
4312 /* data file is a form of cell containing only a limited subset of instructions (var, other data, etc..), in particular nodes */
4313 /* and other instructions are forbidden. */
4314 /* 'data_flag[depth]' is set to trigger verification of this limitation. */
4315 /* Processing is similar to cell. */
4316
4317 char data_interface[LINLENGTH] = {'\0'};
4318 char inst_interface[LINLENGTH] = {'\0'};
4319 char tok0[STRLENGTH] = {'\0'};
4320 char tok1[STRLENGTH] = {'\0'};
4321 char tok2[STRLENGTH] = {'\0'};
4322 char buff[LINLENGTH] = {'\0'};
4323 char sgn1[2] = {'\0'};
4324 char sgn2[2] = {'\0'};
4325 char brc[3] = {'\0'};
4326 char *str1 = (char*) NULL;
4327 char *str2 = (char*) NULL;
4328 time_t time_start;
4329 time_t time_stop;
4330 long v, i, j, d;
4331 unsigned long nl = 0L;
4332 static long num_data = -1L; /* used to obtain unique identifier! */
4333
4334 (void) f1flush((FILE*) NULL); /* just in case, during expansion */
4335
4336 if (Expand_Flag) {
4337 (void) fprintf(STDOUT, "\n#* ");
4338 (void) fprintf(STDERR, " ");
4339 for (j = 0L; j < depth; j++) {
4340 (void) f2printf(STDERR, STDOUT, ">> ");
4341 }
4342 (void) fprintf(STDOUT, ">> %s\n\n", buffer);
4343 (void) fprintf(STDERR, ">> "); /* file name will be printed later */
4344 }
4345 if (0L != width) {
4346 print_error_location("data", mline, mfile);
4347 (void) fprintf(STDERR, " declaration of width is not allowed\n");
4348 /* parsing of instruction may continue */
4349 }
4350 Num_Cells++;
4351 num_data++;
4352 depth++;
4353 if (Max_Depth < depth) { /* record max depth of hierarchy */
4354 Max_Depth = depth;
4355 }
4356 if (depth >= MAXDEPTH) {
4357 mline[depth] = 0UL;
4358 print_error_location("data cell instantiation", mline, mfile);
4359 (void) fprintf(STDERR, " cell hierarchy overflow, currently limited to a depth of %ld\n", MAXDEPTH);
4360 print_limits();
4362 }
4363 (void) snprintf(cell, (size_t) (LINLENGTH-1L), "dat_%ld", num_data); /* build automatic instance name */
4364 if (ISEMPTY(Cell_Name_Prefix[depth-1L])) {
4365 (void) strcpy(Cell_Name_Prefix[depth], cell);
4366 } else {
4367 (void) snprintf(Cell_Name_Prefix[depth], (size_t) (STRLENGTH-1L), "%s__%s", Cell_Name_Prefix[depth-1L], cell);
4368 }
4369 record_cell_nam(Cell_Name_Prefix[depth], depth, mline, mfile);
4370 str = get_token_between_braces(str, brc, tok1);
4371 if ((0 == strcmp(tok1, "data_interface")) && (0 == strcmp(brc, ""))) {
4372 depth--;
4373 print_error_location("parser", mline, mfile);
4374 (void) fprintf(STDERR, " data cell interface is only allowed as head line of a data cell\n");
4376 }
4377 if (ISEMPTY(tok1) || ((0 != strcmp(brc, "\"\"")) && (0 != strcmp(brc, "<>")))) {
4378 str = get_token(str, tok1, false);
4379 v = var_id(tok1);
4380 if ((UNDEFINED == v) || (STRING_DATA_TYPE != Var_List[v].type)) {
4381 mline[depth] = 0UL;
4382 print_error_location("data cell instantiation", mline, mfile);
4383 (void) fprintf(STDERR, " file name is missing or not correct: <%s>\n", tok1);
4385 } else {
4386 str2 = Var_List[v].value;
4387 (void) get_token_between_braces(str2, brc, tok1);
4388 }
4389 }
4390 build_pathname(brc, tok1, Net_Lib_Name, mline, mfile);
4391 (void) strcpy(inst_interface, str); /* instance interface */
4392 (void) strcpy(tok0, Cur_Lib_Name[depth-1L]);
4393 (void) strcpy(Cur_Lib_Name[depth], tok0);
4394 extract_directory(Cur_Lib_Name[depth], tok1, depth); /* follows NAPA file system */
4395 (void) snprintf(Cur_Fil_Name[depth], (size_t) (STRLENGTH-1L), "%s%s", Cur_Lib_Name[depth], tok1);
4396 if ((char*) NULL == strstr(Cur_Fil_Name[depth], ".")) { /* complete file name with dat extension */
4397 (void) strcat(Cur_Fil_Name[depth], ".dat");
4398 }
4399 record_file_nam(depth, mline, mfile);
4400 (void) time(&time_start);
4401 do { /* wait for closing of file produced by generator */
4402 fhandle[depth] = fopen(Cur_Fil_Name[depth], "r");
4403 (void) time(&time_stop);
4404 } while (((FILE*) NULL == fhandle[depth]) && (3L >= ((long) (time_stop-time_start))));
4405 if (Expand_Flag) {
4406 (void) fprintf(STDERR, "Expanding %s\n", Cur_Fil_Name[depth]);
4407 Hierarchy_Flag = true;
4408 }
4409 if ((FILE*) NULL == fhandle[depth]) {
4410 mline[depth] = 0UL;
4411 print_error_location("data cell instantiation", mline, mfile);
4412 (void) fprintf(STDERR, " OUCH!- can't read file <\"%s\">\n", Cur_Fil_Name[depth]);
4414 }
4415 if ((char*) NULL == get_a_line(buff, &nl, fhandle[depth], mline, mfile)) {
4416 mline[depth] = 0UL;
4417 print_error_location("data cell instantiation", mline, mfile);
4418 (void) fprintf(STDERR, " file <\"%s\"> is empty\n", Cur_Fil_Name[depth]);
4420 }
4421 mline[depth] = nl; /* line numbering in data cell file */
4422 str = buff;
4423 if (ISEMPTY(str)) {
4424 print_error_location("data cell interface", mline, mfile);
4425 (void) fprintf(STDERR, " first line of file <\"%s\"> cannot be blank\n", tok1);
4427 }
4428 str = get_token(str, tok2, false); /* get data keyword on 1st line */
4429 if (0 == strcmp(tok2, "cell")) {
4430 print_error_location("data cell interface", mline, mfile);
4431 (void) fprintf(STDERR, " cell file <\"%s\"> cannot be used as a data file\n", tok1);
4433 }
4434 if (0 == strcmp(tok2, "data")) {
4435 str = get_token(str, tok2, false); /* get interface keyword on 1st line */
4436 }
4437 if (0 != strcmp(tok2, "data_interface")) {
4438 print_error_location("data cell interface", mline, mfile);
4439 (void) fprintf(STDERR, " file <\"%s\"> is not a data cell as proper interface is missing on first line\n", tok1);
4441 }
4442 (void) strcpy(data_interface, str); /* get data_interface */
4443
4444 rearrange_data_interfaces(data_interface, inst_interface, mline, mfile); /* by position or by names */
4445
4446 str = inst_interface;
4447 i = 0L;
4448 for (;;) { /* store instantiation parms of cell */
4449 str = get_token(str, Inst_Plist[depth][i], true); /* keep double quotes */
4450 if (0 == strcmp(Inst_Plist[depth][i], "void")) { /* special care to "void" identifier */
4451 (void) snprintf(Inst_Plist[depth][i], (size_t) (LINLENGTH-1L), "_void%ld", Num_Voids);
4452 Num_Voids++;
4453 }
4454 if (0 == strcmp(Inst_Plist[depth][i], "+")) {
4455 str = get_token(str, Inst_Plist[depth][i], false);
4456 } else if (0 == strcmp(Inst_Plist[depth][i], "-")) {
4457 str = get_token(str, tok2, false);
4458 if ((LENGTH(Inst_Plist[depth][i]) + LENGTH(tok2)) < LINLENGTH) {
4459 (void) strcat(Inst_Plist[depth][i], tok2);
4460 } else {
4461 mline[depth] = 0UL;
4462 print_error_location("data cell instantiation", mline, mfile);
4463 (void) fprintf(STDERR, " string overflow, parameter names are too long, use shorter identifiers\n");
4464 print_limits();
4466 }
4467 }
4468 if (ISEMPTY(Inst_Plist[depth][i])) {
4469 break;
4470 }
4471 if ((!is_an_identifier(Inst_Plist[depth][i])) && (UNKNOWN_TYPE == constant_type(Inst_Plist[depth][i]))) {
4472 mline[depth] = 0UL;
4473 print_error_location("data cell instantiation", mline, mfile);
4474 (void) fprintf(STDERR, " <%s> is not a correct data cell parameter\n", Inst_Plist[depth][i]);
4476 }
4477/*
4478 l = var_id(Inst_Plist[depth][i]);
4479 if ((UNDEFINED != l) && (STRING_DATA_TYPE == Var_List[l].type)) {
4480 (void) strcpy(Inst_Plist[depth][i], Var_List[l].value);
4481 }
4482*/
4483 i++;
4484 if (MAXPARMS <= i) {
4485 mline[depth] = 0UL;
4486 print_error_location("data cell instantiation", mline, mfile);
4487 (void) fprintf(STDERR, " overflow, too many parameters (max %ld) for data instantiation\n", MAXPARMS);
4488 print_limits();
4490 }
4491 }
4492 str = data_interface;
4493 d = 0L;
4494 for (;;) { /* store definition parms of cell */
4495 str = get_token(str, Cell_Plist[depth][d], false); /* drop double quotes */
4496 if ((0 == strcmp(Cell_Plist[depth][d], "+")) || (0 == strcmp(Cell_Plist[depth][d], "-"))) {
4497 print_error_location("data cell interface", mline, mfile);
4498 (void) fprintf(STDERR, " formal parameter cannot be signed\n");
4499 str = get_token(str, Cell_Plist[depth][d], false);
4500 /* parsing of instruction may continue */
4501 }
4502 if (ISEMPTY(Cell_Plist[depth][d])) {
4503 break;
4504 }
4505 if ('$' != (Cell_Plist[depth][d])[0]) {
4506 print_error_location("data cell interface", mline, mfile);
4507 (void) fprintf(STDERR, " formal parameter <%s> must begin with letter '$'\n", Cell_Plist[depth][d]);
4509 }
4510 if (MAXPARMS <= d) {
4511 print_error_location("data cell interface", mline, mfile);
4512 (void) fprintf(STDERR, " overflow, too many formal parameters (max %ld) for data instantiation\n", MAXPARMS);
4513 print_limits();
4515 }
4516 d++;
4517 }
4518 if (i != d) {
4519 mline[depth] = 0UL;
4520 print_error_location("data cell instantiation", mline, mfile);
4521 (void) fprintf(STDERR, " data cell file pathname: \"%s\"\n", Cur_Fil_Name[depth]);
4522 (void) fprintf(STDERR, " discrepancy between the number of formal and actual parameters\n");
4523 str1 = data_interface;
4524 str2 = inst_interface;
4525 for (;;) {
4526 (void) strcpy(sgn1, " ");
4527 if (ISNOTEMPTY(str1)) {
4528 str1 = get_token(str1, tok1, true);
4529 if ((((0 == strcmp(tok1, "+")) || (0 == strcmp(tok1, "-"))) && ISNOTEMPTY(str1))) {
4530 (void) strcpy(sgn1, tok1);
4531 str1 = get_token(str1, tok1, true);
4532 }
4533 } else {
4534 (void) strcpy(tok1, "?");
4535 }
4536 (void) strcpy(sgn2, " ");
4537 if (ISNOTEMPTY(str2)) {
4538 str2 = get_token(str2, tok2, true);
4539 if ((((0 == strcmp(tok2, "+")) || (0 == strcmp(tok2, "-"))) && ISNOTEMPTY(str2))) {
4540 (void) strcpy(sgn2, tok2);
4541 str2 = get_token(str2, tok2, true);
4542 }
4543 } else {
4544 (void) strcpy(tok2, "?");
4545 }
4546 if ( (0 == strcmp(tok1, "?")) && (0 == strcmp(tok2, "?")) ) {
4547 break;
4548 }
4549 (void) fprintf(STDERR, " %s%-10s <-> %s%-10s\n", sgn1, tok1, sgn2, tok2);
4550 }
4551 (void) fprintf(STDERR, "\n");
4553 }
4554 Cell_Num_Parms[depth] = i;
4555 data_flag[depth] = true;
4556 return;
4557}
long f2printf(FILE *fp1, FILE *fp2, char *fmt,...)
Definition fc.c:157
void print_limits(void)
Definition fc.c:56
char * get_a_line(char *buf, unsigned long *nl, FILE *fp, unsigned long *mlin, const unsigned long *mfil)
Definition fc.c:100
long constant_type(char *identifier)
Definition id.c:1130
void record_file_nam(long d, const unsigned long *mlin, const unsigned long *mfil)
Definition lp.c:5178
void rearrange_data_interfaces(char *data_if, char *inst_if, const unsigned long *mlin, const unsigned long *mfil)
Definition lp.c:5025
void record_cell_nam(const char *nam, long cur_depth, unsigned long *mlin, const unsigned long *mfil)
Definition lp.c:5158
EXTERN char Inst_Plist[31L][127L][16383L]
Definition napa.h:937
EXTERN long Num_Voids
Definition napa.h:837
EXTERN char Cell_Name_Prefix[31L][2047L]
Definition napa.h:945
#define MAXPARMS
Definition napa.h:200
EXTERN int Hierarchy_Flag
Definition napa.h:860
EXTERN long Max_Depth
Definition napa.h:797
EXTERN int Expand_Flag
Definition napa.h:854
#define STDOUT
Definition napa.h:104
EXTERN char Cur_Lib_Name[31L][2047L]
Definition napa.h:932
EXTERN long Cell_Num_Parms[31L]
Definition napa.h:934
EXTERN char Cur_Fil_Name[31L][2047L]
Definition napa.h:931
EXTERN long Num_Cells
Definition napa.h:803
EXTERN char * Net_Lib_Name
Definition napa.h:915
EXTERN char Cell_Plist[31L][127L][16383L]
Definition napa.h:936
void extract_directory(char *pn, char *fn, long depth)
Definition tk.c:339
void build_pathname(const char *brc, char *tok, const char *path, const unsigned long *mlin, const unsigned long *mfil)
Definition tk.c:230
int f1flush(FILE *fp)
Definition tk.c:1843

References build_pathname(), Cell_Name_Prefix, Cell_Num_Parms, Cell_Plist, constant_type(), Cur_Fil_Name, Cur_Lib_Name, Expand_Flag, extract_directory(), f1flush(), f2printf(), get_a_line(), get_token(), get_token_between_braces(), Hierarchy_Flag, Inst_Plist, is_an_identifier(), ISEMPTY, ISNOTEMPTY, LENGTH, LINLENGTH, Max_Depth, MAXDEPTH, MAXPARMS, Net_Lib_Name, Num_Cells, Num_Voids, print_error_banner_and_exit(), print_error_location(), print_limits(), rearrange_data_interfaces(), record_cell_nam(), record_file_nam(), STDERR, STDOUT, STRING_DATA_TYPE, STRLENGTH, UNDEFINED, UNKNOWN_TYPE, var_id(), and Var_List.

Referenced by line_parsing().

◆ get_debug()

void get_debug ( char * str)

Definition at line 3126 of file lp.c.

3126 {
3127
3128 /* INSTRUCTION: DEBUG */
3129 /* - debug level keywords */
3130
3131 char tok[STRLENGTH] = {'\0'};
3132 char sgn[2] = {'\0'};
3133 long d, i;
3134
3135 if (0L != width) {
3136 print_warning_location("debug", mline, mfile);
3137 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width);
3138 }
3139 if (ISEMPTY(str)) {
3140 print_error_location("debug", mline, mfile);
3141 (void) fprintf(STDERR, " debug identifier is missing\n");
3142 return;
3143 }
3144 while (ISNOTEMPTY(str)) {
3145 str = get_sign_and_token(str, sgn, tok);
3146 if (ISNOTEMPTY(sgn)) {
3147 print_error_location("debug", mline, mfile);
3148 (void) fprintf(STDERR, " no sign expected in front of a debug identifier <%s>\n", tok);
3149 /* parsing of instruction may continue */
3150 }
3151 i = debug_id(tok);
3152 if (UNDEFINED != i) {
3153 (Debug_List[i].usage)++;
3154 return; /* return ! no duplication of identical definition */
3155 }
3156 if (is_an_instruction(tok)) {
3157 print_error_location("debug", mline, mfile);
3158 (void) fprintf(STDERR, " <%s>, an instruction cannot be used as debug directive\n", tok);
3160 } else if (UNDEFINED != directive_id(tok)) {
3161 print_error_location("debug", mline, mfile);
3162 (void) fprintf(STDERR, " <%s>, a directive cannot be used as debug directive\n", tok);
3164 } else if (UNDEFINED != node_id(tok)) {
3165 print_error_location("debug", mline, mfile);
3166 (void) fprintf(STDERR, " <%s>, a node cannot be used as debug directive\n", tok);
3167 } else if (UNDEFINED != var_id(tok)) {
3168 print_error_location("debug", mline, mfile);
3169 (void) fprintf(STDERR, " <%s>, a variable cannot be used as debug directive\n", tok);
3170 } else if (UNDEFINED != record_id(tok)) {
3171 print_error_location("debug", mline, mfile);
3172 (void) fprintf(STDERR, " <%s>, a record cannot be used as debug directive\n", tok);
3173 } else if (UNDEFINED != array_id(tok)) {
3174 print_error_location("debug", mline, mfile);
3175 (void) fprintf(STDERR, " <%s>, an array cannot be used as debug directive\n", tok);
3176 } else if (('"' == tok[0]) && ('"' == tok[LENGTH(tok)-1L])) {
3177 print_error_location("debug", mline, mfile);
3178 (void) fprintf(STDERR, " <%s>, a string cannot be used as debug directive\n", tok);
3179 }
3180 if (!is_an_identifier(tok)) {
3181 print_error_location("debug", mline, mfile);
3182 (void) fprintf(STDERR, " <%s> is not a NAPA identifier\n", tok);
3183 }
3184 strcpy_alloc(&(Debug_List[Num_Debugs].name), tok, mline, mfile); /* id */
3185 Debug_List[Num_Debugs].usage = 1L;
3186 for (d = 0L; d < MAXDEPTH; d++) {
3187 Debug_List[Num_Debugs].mline[d] = mline[d]; /* record line for identification */
3188 Debug_List[Num_Debugs].mfile[d] = mfile[d]; /* record file for identification */
3189 }
3190 increment_debug_number("debug");
3191 Debug_Flag = true;
3192 }
3193 return;
3194}
void increment_debug_number(const char *kind)
Definition id.c:241
int is_an_instruction(const char *identifier)
Definition id.c:1468
long debug_id(const char *identifier)
Definition id.c:685
EXTERN long Num_Debugs
Definition napa.h:809
EXTERN DEBUG_TYPE Debug_List[63L]
Definition napa.h:952
EXTERN int Debug_Flag
Definition napa.h:848

References array_id(), Debug_Flag, debug_id(), Debug_List, directive_id(), get_sign_and_token(), increment_debug_number(), is_an_identifier(), is_an_instruction(), ISEMPTY, ISNOTEMPTY, LENGTH, MAXDEPTH, node_id(), Num_Debugs, print_error_banner_and_exit(), print_error_location(), print_warning_location(), record_id(), STDERR, strcpy_alloc(), STRLENGTH, UNDEFINED, and var_id().

Referenced by line_parsing().

◆ get_decimate()

void get_decimate ( char * str)

Definition at line 1836 of file lp.c.

1836 {
1837
1838 /* INSTRUCTION: DECIMATE */
1839 /* - "fs" optional */
1840 /* - decimation value mandatory, integer > 0 */
1841 /* - decimation offset optional, integer > 0 */
1842
1843 char tok1[STRLENGTH] = {'\0'};
1844 char tok2[STRLENGTH] = {'\0'};
1845 char sgn[2] = {'\0'};
1846 long ltemp;
1847 long ref;
1848 long d, v;
1849
1850 if (data_flag[depth]) {
1851 print_error_location("data", mline, mfile);
1852 (void) fprintf(STDERR, " instruction 'decimate' is not allowed in a data cell file\n");
1854 }
1855 if (0L != width) {
1856 print_warning_location("decimate", mline, mfile);
1857 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width);
1858 }
1859 str = get_sign_and_token(str, sgn, tok1);
1860 if (ISEMPTY(tok1)) {
1861 print_error_location("decimate", mline, mfile);
1862 (void) fprintf(STDERR, " decimation value is missing\n");
1864 }
1865 if (0 == strcmp(tok1, "fs")) {
1866 ref = 1L; /* reference: absolute */
1867 str = get_sign_and_token(str, sgn, tok1);
1868 Drop_Flag = false; /* reset Drop_Flag as it is an absolute reference */
1869 } else {
1870 ref = 0L; /* reference: relative to previous segment */
1871 }
1872 (void) snprintf(tok2, (size_t) (STRLENGTH-1L), "%s%s", sgn, tok1); /* signed integer value */
1873 v = var_id(tok2);
1874 while (v != UNDEFINED) {
1875 (void) strcpy(tok2, Var_List[v].value);
1876 Var_List[v].used = true;
1877 v = var_id(tok2);
1878 }
1879 if (1 != sscanf(tok2, "%li", &ltemp)) {
1880 print_error_location("decimate", mline, mfile);
1881 (void) fprintf(STDERR, " rate is not a well-formed positive C integer <%s>,\n", tok2);
1882 (void) fprintf(STDERR, " if <%s> is a variable, it should be defined as a number before this instruction\n", tok2);
1884 }
1885 if (0L >= ltemp) {
1886 print_error_location("decimate", mline, mfile);
1887 (void) fprintf(STDERR, " rate is not a positive integer <%s>\n", tok2);
1889 }
1890 Segment_List[Num_Segments].rate = (double) ltemp;
1891 str = get_sign_and_token(str, sgn, tok1);
1892 (void) snprintf(tok2, (size_t) (STRLENGTH-1L), "%s%s", sgn, tok1); /* signed integer value */
1893 if (ISNOTEMPTY(tok2)) {
1894 v = var_id(tok2);
1895 while (v != UNDEFINED) {
1896 (void) strcpy(tok2, Var_List[v].value);
1897 Var_List[v].used = true;
1898 v = var_id(tok2);
1899 }
1900 if (1 != sscanf(tok2, "%li", &ltemp)) {
1901 print_error_location("decimate", mline, mfile);
1902 (void) fprintf(STDERR, " the decimation offset is not a well-formed positive C integer <%s>,\n", tok2);
1903 (void) fprintf(STDERR, " if <%s> is a variable, it should be defined as a number before this instruction\n", tok2);
1905 }
1906 if (0L > ltemp) {
1907 print_error_location("decimate", mline, mfile);
1908 (void) fprintf(STDERR, " the decimation offset is not a positive integer <%s>\n", tok2);
1910 }
1911 Segment_List[Num_Segments].offset = (double) ltemp;
1912 if (Segment_List[Num_Segments].offset >= Segment_List[Num_Segments].rate) {
1913 print_error_location("decimate", mline, mfile);
1914 (void) fprintf(STDERR, " starting value <%g> must be strictly smaller", Segment_List[Num_Segments].offset);
1915 (void) fprintf(STDERR, " than the decimate ratio <%g>\n", Segment_List[Num_Segments].rate );
1917 }
1918 } else { /* default value is zero */
1919 Segment_List[Num_Segments].offset = 0.0;
1920 }
1922 Segment_List[Num_Segments].ref = ref;
1923 Segment_List[Num_Segments].used1 = false;
1924 Segment_List[Num_Segments].used2 = false;
1925 Segment_List[Num_Segments].used3 = false;
1926 if (!Drop_Flag) { /* no drop instruction before */
1927 Segment_List[Num_Segments].periodic = true;
1928 } else {
1929 Segment_List[Num_Segments].periodic = false; /* periodic sampling not guaranteed */
1930 }
1931 for (d = 0L; d < MAXDEPTH; d++) {
1932 Segment_List[Num_Segments].mline[d] = mline[d];
1933 Segment_List[Num_Segments].mfile[d] = mfile[d];
1934 }
1935 increment_segment_number("decimate");
1936 return;
1937}
void increment_segment_number(const char *kind)
Definition id.c:479
#define DECIMATE_SEGMENT_TYPE
Definition napa.h:351
EXTERN int Drop_Flag
Definition napa.h:851

References DECIMATE_SEGMENT_TYPE, Drop_Flag, get_sign_and_token(), increment_segment_number(), ISEMPTY, ISNOTEMPTY, MAXDEPTH, Num_Segments, print_error_banner_and_exit(), print_error_location(), print_warning_location(), Segment_List, STDERR, STRLENGTH, UNDEFINED, var_id(), and Var_List.

Referenced by line_parsing().

◆ get_declare()

void get_declare ( char * str)

Definition at line 2679 of file lp.c.

2679 {
2680
2681 /* INSTRUCTION: DECLARE */
2682 /* - qualifier mandatory */
2683 /* - identifier at least one */
2684
2685 long number;
2686 long type;
2687 char buf[STRLENGTH] = {'\0'};
2688 char tok1[LINLENGTH] = {'\0'};
2689 char tok2[LINLENGTH] = {'\0'};
2690 char sgn[2] = {'\0'};
2691 char brc[3] = {'\0'};
2692 long d;
2693
2694 if (0L != width) {
2695 print_warning_location("declare", mline, mfile);
2696 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width);
2697 }
2698 str = get_token_between_braces(str, brc, tok1);
2699 if (0 != strcmp(brc, "()")) {
2700 print_error_location("declare", mline, mfile);
2701 (void) fprintf(STDERR, " declaration qualifier is missing\n");
2702 return;
2703 }
2704 if (0 == strcmp(tok1, "constant")) {
2705 type = CONSTANT_TYPE;
2706 } else if (0 == strcmp(tok1, "digital" )) {
2707 type = DIGITAL_DATA_TYPE;
2708 } else if (0 == strcmp(tok1, "analog" )) {
2709 type = ANALOG_DATA_TYPE;
2710 } else if (0 == strcmp(tok1, "string" )) {
2711 type = STRING_DATA_TYPE;
2712 } else if (0 == strcmp(tok1, "true" )) { /* SPECIAL HANDLING !!! not a type declaration ! */
2713 type = BOOLEAN_DATA_TYPE;
2714 } else if (ISEMPTY(tok1)) {
2715 type = UNKNOWN_TYPE;
2716 } else {
2717 print_error_location("declare", mline, mfile);
2718 (void) fprintf(STDERR, " (%s) is not a valid declaration qualifier\n", tok1);
2719 (void) fprintf(STDERR, " valid qualifiers are:\n");
2720 (void) fprintf(STDERR, " (digital)\n");
2721 (void) fprintf(STDERR, " (analog)\n");
2722 (void) fprintf(STDERR, " (string)\n");
2723 (void) fprintf(STDERR, " (constant)\n");
2724 (void) fprintf(STDERR, " (true)\n");
2725 return;
2726 }
2727 if (ISEMPTY(str)) {
2728 print_error_location("declare", mline, mfile);
2729 (void) fprintf(STDERR, " node or variable identifier is missing\n");
2730 return;
2731 }
2732 if (BOOLEAN_DATA_TYPE == type) { /* special case ! a kind of init */
2733 if (ISEMPTY(str)) {
2734 print_error_location("declare", mline, mfile);
2735 (void) fprintf(STDERR, " declare expression is missing\n");
2736 return;
2737 }
2738 (void) snprintf(buf, (size_t) 31, "$declare$_%ld", Num_Inits);
2739 increment_init_number("declare");
2740 clean_parentheses(str);
2741 resolve_pathnames(str, depth); /* resolve pathname using conventions */
2742 strcpy_alloc(&(Var_List[Num_Vars].name1), buf, mline, mfile); /* keyword: $declare$_.. */
2743 strcpy_alloc(&(Var_List[Num_Vars].name2), buf, mline, mfile); /* copy of name */
2744 Var_List[Num_Vars].aliased = false; /* not aliased */
2745 strcpy_alloc(&(Var_List[Num_Vars].value), str, mline, mfile); /* unprocessed value */
2746 strcpy_alloc(&(Var_List[Num_Vars].comment), "", mline, mfile); /* currently empty */
2747 Var_List[Num_Vars].type = UNKNOWN_TYPE; /* will be defined later */
2748 Var_List[Num_Vars].used = true; /* don't care */
2749 Var_List[Num_Vars].declare = UNKNOWN_TYPE;
2750 Var_List[Num_Vars].external = false;
2751 Var_List[Num_Vars].event = false;
2752 Var_List[Num_Vars].determined = true;
2753 Var_List[Num_Vars].constant = false; /* don't care */
2754 Var_List[Num_Vars].segment = Num_Segments - 1L; /* record segment level */
2755 for (d = 0L; d < MAXDEPTH; d++) {
2756 Var_List[Num_Vars].mline[d] = mline[d]; /* record line for identification */
2757 Var_List[Num_Vars].mfile[d] = mfile[d]; /* record file for identification */
2758 }
2759 increment_var_number("declare");
2760 return;
2761 }
2762 if (UNKNOWN_TYPE != type) { /* regular declaration */
2763 number = 1L;
2764 for (;;) {
2765 str = get_sign_and_token(str, sgn, tok1); /* sign MUST be ignored as in a CELL, */
2766 if (ISEMPTY(tok1)) { /* 'declare' could receive signed var */
2767 break;
2768 }
2769 strcpy_alloc(&(Declare_List[Num_Declares].name), tok1, mline, mfile); /* identifier */
2770 Declare_List[Num_Declares].type = type; /* type */
2771 Declare_List[Num_Declares].number = number; /* number to identify position */
2772 for (d = 0L; d < MAXDEPTH; d++) {
2773 Declare_List[Num_Declares].mline[d] = mline[d]; /* record line for identification */
2774 Declare_List[Num_Declares].mfile[d] = mfile[d]; /* record file for identification */
2775 }
2776 increment_declare_number("declare");
2777 number++;
2778 }
2779 } else { /* group of identifiers of same type */
2780 (void) strcpy(tok2, "");
2781 for (;;) {
2782 str = get_sign_and_token(str, sgn, tok1); /* sign IS ignored as in a CELL, a */
2783 if (ISEMPTY(tok1)) { /* 'declare' could receive signed var */
2784 break;
2785 }
2786 (void) strcat(tok2, " ");
2787 (void) strcat(tok2, tok1);
2788 }
2789 str = tok2;
2790 strcpy_alloc(&(Declare_Common_List[Num_Declare_Commons].value), str, mline, mfile);
2791 for (d = 0L; d < MAXDEPTH; d++) {
2792 Declare_Common_List[Num_Declare_Commons].mline[d] = mline[d]; /* record line for identification */
2793 Declare_Common_List[Num_Declare_Commons].mfile[d] = mfile[d]; /* record file for identification */
2794 }
2795 increment_common_number("declare");
2796 }
2797 return;
2798}
void increment_declare_number(const char *kind)
Definition id.c:254
void increment_init_number(const char *kind)
Definition id.c:360
void increment_common_number(const char *kind)
Definition id.c:228
void increment_var_number(const char *kind)
Definition id.c:545
EXTERN DECLARE_COMMON_TYPE Declare_Common_List[255L]
Definition napa.h:954
EXTERN long Num_Vars
Definition napa.h:836
EXTERN DECLARE_TYPE Declare_List[1023L]
Definition napa.h:953
#define CONSTANT_TYPE
Definition napa.h:344
EXTERN long Num_Declares
Definition napa.h:810
EXTERN long Num_Inits
Definition napa.h:819
#define BOOLEAN_DATA_TYPE
Definition napa.h:341
EXTERN long Num_Declare_Commons
Definition napa.h:806

References ANALOG_DATA_TYPE, BOOLEAN_DATA_TYPE, clean_parentheses(), CONSTANT_TYPE, Declare_Common_List, Declare_List, DIGITAL_DATA_TYPE, get_sign_and_token(), get_token_between_braces(), increment_common_number(), increment_declare_number(), increment_init_number(), increment_var_number(), ISEMPTY, LINLENGTH, MAXDEPTH, Num_Declare_Commons, Num_Declares, Num_Inits, Num_Segments, Num_Vars, print_error_location(), print_warning_location(), resolve_pathnames(), STDERR, strcpy_alloc(), STRING_DATA_TYPE, STRLENGTH, UNKNOWN_TYPE, and Var_List.

Referenced by get_var(), and line_parsing().

◆ get_directive()

void get_directive ( char * str1)

Definition at line 1661 of file lp.c.

1661 {
1662
1663 /* INSTRUCTION: DIRECTIVE */
1664 /* - directive identifier mandatory, no check */
1665 /* - directive parameter optional */
1666 /* - directive definition optional, no check */
1667
1668 /* Only identical definitions may be repeated in netlist */
1669
1670 /* Parameters of these directives are stored in tables for */
1671 /* further processing */
1672
1673 char tok1[STRLENGTH] = {'\0'};
1674 char tok2[STRLENGTH] = {'\0'};
1675 char tok3[STRLENGTH] = {'\0'};
1676 char brc[3] = {'\0'};
1677 char sgn[2] = {'\0'};
1678 char *str2 = (char*) NULL;
1679 long d, i;
1680 int flag;
1681 flag = false;
1682 if (0L != width) {
1683 print_warning_location("directive", mline, mfile);
1684 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width);
1685 }
1686 str2 = str1;
1687 str2 = get_token_between_braces(str2, brc, tok1);
1688 if (0 == strcmp(brc, "()")) { /* it means no check of usage */
1689 flag = true;
1690 str1 = str2;
1691 } else {
1692 str1 = get_sign_and_token(str1, sgn, tok1);
1693 if (ISNOTEMPTY(sgn)) {
1694 print_error_location("directive", mline, mfile);
1695 (void) fprintf(STDERR, " no sign expected\n");
1696 return;
1697 }
1698 }
1699 if (ISEMPTY(tok1)) {
1700 print_error_location("directive", mline, mfile);
1701 (void) fprintf(STDERR, " directive identifier is missing\n");
1702 return;
1703 }
1704 if (!is_an_identifier(tok1)) {
1705 print_error_location("directive", mline, mfile);
1706 (void) fprintf(STDERR, " directive identifier <%s> is not a NAPA identifier\n", tok1);
1707 return;
1708 }
1709 if (is_a_keyword(tok1)) {
1710 print_error_location("directive", mline, mfile);
1711 (void) fprintf(STDERR, " directive identifier <%s> is a reserved NAPA keyword\n", tok1);
1712 /* parsing of instruction may continue */
1713 }
1714 i = directive_id(tok1);
1715 if (UNDEFINED != i) {
1716 if (0 != strcmp(Directive_List[i].value, str1)) {
1717 print_error_location("directive", mline, mfile);
1718 (void) fprintf(STDERR, " <%s> is redefining a directive previously defined\n", tok1);
1719 print_location(Directive_List[i].mline, Directive_List[i].mfile);
1720 /* parsing of instruction may continue */
1721 return;
1722 } else {
1723 return; /* no duplication of identical definition */
1724 }
1725 }
1726 i = alias_id(tok1);
1727 if (UNDEFINED != i) {
1728 print_error_location("directive", mline, mfile);
1729 (void) fprintf(STDERR, " definition <%s> is colliding an alias defined\n", tok1);
1730 print_location(Alias_List[i].mline, Alias_List[i].mfile);
1731 /* parsing of instruction may continue */
1732 }
1733 i = node_id(tok1);
1734 if (UNDEFINED != i) {
1735 print_error_location("directive", mline, mfile);
1736 (void) fprintf(STDERR, " definition <%s> is colliding a node defined\n", tok1);
1737 print_location(Var_List[i].mline, Var_List[i].mfile);
1738 /* parsing of instruction may continue */
1739 return;
1740 }
1741 i = var_id(tok1);
1742 if (UNDEFINED != i) {
1743 print_error_location("directive", mline, mfile);
1744 (void) fprintf(STDERR, " definition <%s> is colliding a variable defined\n", tok1);
1745 print_location(Var_List[i].mline, Var_List[i].mfile);
1746 /* parsing of instruction may continue */
1747 return;
1748 }
1749 i = record_id(tok1);
1750 if (UNDEFINED != i) {
1751 print_error_location("directive", mline, mfile);
1752 (void) fprintf(STDERR, " definition <%s> is colliding a record defined\n", tok1);
1753 print_location(Record_List[i].mline, Record_List[i].mfile);
1754 /* parsing of instruction may continue */
1755 return;
1756 }
1757 i = array_id(tok1);
1758 if (UNDEFINED != i) {
1759 print_error_location("directive", mline, mfile);
1760 (void) fprintf(STDERR, " definition <%s> is colliding an array defined\n", tok1);
1761 print_location(Array_List[i].mline, Array_List[i].mfile);
1762 /* parsing of instruction may continue */
1763 return;
1764 }
1765 strcpy_alloc(&(Directive_List[Num_Directives].name), tok1, mline,mfile); /* id */
1766 str2 = str1; /* keep char pointer */
1767 str1 = get_token_between_braces(str1, brc, tok2); /* process following NAPA file system */
1768 if (0 == strcmp(brc, "()")) { /* this is a macro function */
1769 Directive_List[Num_Directives].function = true; /* macro function */
1770 (void) strcpy(tok3, "(");
1771 (void) strcat(tok3, tok2);
1772 (void) strcat(tok3, ")");
1773 strcpy_alloc(&(Directive_List[Num_Directives].parms), tok2, mline,mfile); /* macro function parameters */
1774 } else {
1775 Directive_List[Num_Directives].function = false; /* simple macro */
1776 strcpy_alloc(&(Directive_List[Num_Directives].parms), "", mline,mfile); /* no parameter */
1777 str1 = str2; /* recover char pointer */
1778 }
1779 (void) strcpy(tok2, str1);
1780 strcpy_alloc(&(Directive_List[Num_Directives].value), tok2, mline,mfile); /* unprocessed */
1781 if (!flag) {
1782 Directive_List[Num_Directives].used = false; /* usage will be checked at run time */
1783 } else {
1784 Directive_List[Num_Directives].used = true; /* no check on usage will be performed */
1785 }
1786 for (d = 0L; d < MAXDEPTH; d++) {
1787 Directive_List[Num_Directives].mline[d] = mline[d]; /* record line for identification */
1788 Directive_List[Num_Directives].mfile[d] = mfile[d]; /* record file for identification */
1789 }
1790 increment_directive_number("directive");
1791 return;
1792}
void increment_directive_number(const char *kind)
Definition id.c:267
EXTERN long Num_Directives
Definition napa.h:812

References alias_id(), Alias_List, array_id(), Array_List, directive_id(), Directive_List, get_sign_and_token(), get_token_between_braces(), increment_directive_number(), is_a_keyword(), is_an_identifier(), ISEMPTY, ISNOTEMPTY, MAXDEPTH, node_id(), Num_Directives, print_error_location(), print_location(), print_warning_location(), record_id(), Record_List, STDERR, strcpy_alloc(), STRLENGTH, UNDEFINED, var_id(), and Var_List.

Referenced by line_parsing().

◆ get_drop()

void get_drop ( char * str)

Definition at line 2015 of file lp.c.

2015 {
2016
2017 /* INSTRUCTION: DROP */
2018 /* - "fs" optional */
2019 /* - C condition mandatory, no check */
2020 /* C conditional statement is stored for further processing */
2021
2022 char tok1[STRLENGTH] = {'\0'};
2023 char *s = (char*) NULL;
2024 long ref;
2025 long d;
2026
2027 if (data_flag[depth]) {
2028 print_error_location("data", mline, mfile);
2029 (void) fprintf(STDERR, " instruction 'drop' is not allowed in a data cell file\n");
2031 }
2032 if (0L != width) {
2033 print_warning_location("drop", mline, mfile);
2034 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width);
2035 }
2036 if (ISEMPTY(str)) {
2037 print_error_location("drop", mline, mfile);
2038 (void) fprintf(STDERR, " C conditional expression is missing\n");
2040 }
2041 s = str;
2042 s = get_token(s, tok1, false);
2043 if (0 == strcmp(tok1, "fs")) {
2044 ref = 1L; /* reference: relative to previous segment */
2045 str = s;
2046 } else {
2047 ref = 0L; /* reference: absolute */
2048 }
2049 clean_parentheses(str);
2050 resolve_pathnames(str, depth); /* resolve pathname using conventions */
2051 strcpy_alloc(&(Segment_List[Num_Segments].value), str, mline, mfile);
2053 Segment_List[Num_Segments].ref = ref;
2054 Segment_List[Num_Segments].offset = 0.0;
2055 Segment_List[Num_Segments].used1 = false;
2056 Segment_List[Num_Segments].used2 = false;
2057 Segment_List[Num_Segments].used3 = false;
2058 Segment_List[Num_Segments].periodic = false; /* periodic sampling not guaranteed */
2059 for (d = 0L; d < MAXDEPTH; d++) {
2060 Segment_List[Num_Segments].mline[d] = mline[d];
2061 Segment_List[Num_Segments].mfile[d] = mfile[d];
2062 }
2064 Drop_Flag = true;
2065 return;
2066}
#define DROP_SEGMENT_TYPE
Definition napa.h:353

References clean_parentheses(), Drop_Flag, DROP_SEGMENT_TYPE, get_token(), increment_segment_number(), ISEMPTY, MAXDEPTH, Num_Segments, print_error_banner_and_exit(), print_error_location(), print_warning_location(), resolve_pathnames(), Segment_List, STDERR, strcpy_alloc(), and STRLENGTH.

Referenced by line_parsing().

◆ get_dump()

void get_dump ( char * str)

Definition at line 4168 of file lp.c.

4168 {
4169
4170 /* INSTRUCTION: DUMP */
4171 /* - file pathname mandatory */
4172 /* - conditional expression optional */
4173 /* Dump instruction should be unique */
4174
4175 /* Conditional expression is stored for further processing */
4176
4177 char tok1[STRLENGTH] = {'\0'};
4178 char tok2[STRLENGTH] = {'\0'};
4179 char brc[3] = {'\0'};
4180 char *str1 = (char*) NULL;
4181 long v, d;
4182 int i;
4183
4184 if (data_flag[depth]) {
4185 print_error_location("data", mline, mfile);
4186 (void) fprintf(STDERR, " instruction 'dump' is not allowed in a data cell file\n" );
4187 return;
4188 }
4189 if (0L != width) {
4190 print_warning_location("dump", mline, mfile);
4191 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width );
4192 }
4193 if (Dump_Flag) {
4194 print_warning_location("dump", mline, mfile);
4195 (void) fprintf(STDERR, " dump already defined, previous definition is overwritten\n");
4196 }
4197 str = get_token_between_braces(str, brc, tok1);
4198 if (ISEMPTY(tok1) || (0 != strcmp(brc, "\"\""))) {
4199 str = get_token(str, tok1, false);
4200 v = var_id(tok1);
4201 if ((UNDEFINED == v) || (STRING_DATA_TYPE != Var_List[v].type)) {
4202 mline[depth] = 0UL;
4203 print_error_location("dump", mline, mfile);
4204 if (0 == strcmp(tok1, "when")) {
4205 (void) fprintf(STDERR, " file name is missing\n");
4206 } else {
4207 (void) fprintf(STDERR, " file name is missing or not correct: <%s>\n", tok1);
4208 }
4209 return;
4210 }
4211 str1 = Var_List[v].value;
4212 (void) get_token_between_braces(str1, brc, tok1);
4213 }
4214 resolve_pathnames(tok1, depth); /* resolve pathname using conventions */
4215 simplify_pathname(tok1);
4216 for (i = 0; i < Num_IOs; i++) {
4217 if (0 == fnstrcmp(IO_List[i].fname, tok2)) {
4218 print_error_location("dump", mline, mfile);
4219 (void) fprintf(STDERR, " collision between I/O streams, <%s> is already defined", tok2);
4220 if (INPUT_TYPE == IO_List[i].type) {
4221 (void) fprintf(STDERR, " as input\n");
4222 }
4223 if (OUTPUT_TYPE == IO_List[i].type) {
4224 (void) fprintf(STDERR, " as output\n");
4225 }
4226 }
4227 }
4228 strcpy_alloc(&(Dump_List.fname), tok1, mline, mfile); /* dump_File_Name */
4229 (void) strcpy(tok2, str); /* get the dump condition as it is */
4230 if (ISEMPTY(tok2)) {
4231 print_error_location("dump", mline, mfile);
4232 (void) fprintf(STDERR, " C conditional expression is missing\n");
4233 return;
4234 }
4235 clean_parentheses(tok2);
4236 strcpy_alloc(&(Dump_List.condition), tok2, mline, mfile); /* unprocessed condition */
4237 Dump_List.segment = Num_Segments - 1L; /* record segment level */
4238 Segment_List[Num_Segments-1L].used3 = true;
4239 for (d = 0L; d < MAXDEPTH; d++) {
4240 Dump_List.mline[d] = mline[d]; /* record line for identification */
4241 Dump_List.mfile[d] = mfile[d]; /* record file for identification */
4242 }
4243 Dump_Flag = true;
4244 return;
4245}
EXTERN int Dump_Flag
Definition napa.h:852
#define INPUT_TYPE
Definition napa.h:358
EXTERN long Num_IOs
Definition napa.h:822
EXTERN DUMP_TYPE Dump_List
Definition napa.h:972
#define OUTPUT_TYPE
Definition napa.h:359
EXTERN IO_TYPE IO_List[63L]
Definition napa.h:961
int fnstrcmp(char const *a, char const *b)
Definition tk.c:1828
void simplify_pathname(char *pnam)
Definition tk.c:1543

References clean_parentheses(), Dump_Flag, Dump_List, fnstrcmp(), get_token(), get_token_between_braces(), INPUT_TYPE, IO_List, ISEMPTY, MAXDEPTH, Num_IOs, Num_Segments, OUTPUT_TYPE, print_error_location(), print_warning_location(), resolve_pathnames(), Segment_List, simplify_pathname(), STDERR, strcpy_alloc(), STRING_DATA_TYPE, STRLENGTH, UNDEFINED, var_id(), and Var_List.

Referenced by line_parsing().

◆ get_event()

void get_event ( const char * str)

Definition at line 1299 of file lp.c.

1299 {
1300
1301 /* INSTRUCTION: EVENT */
1302 /* - (new) optional modifier */
1303 /* - formula */
1304
1305 char buf1[LINLENGTH] = {'\0'};
1306 char buf2[LINLENGTH] = {'\0'};
1307 char *str1 = (char*) NULL;
1308 char *str2 = (char*) NULL;
1309 (void) strcpy(buf1, str);
1310 (void) strcpy(buf2, str);
1311 str1 = buf1;
1312 str2 = buf2;
1313 get_var(str1, "event");
1314 get_update(str2, "event");
1315 return;
1316}
void get_update(char *str, const char *instruction)
Definition lp.c:2126
void get_var(char *str, const char *instruction)
Definition lp.c:965

References get_update(), get_var(), and LINLENGTH.

Referenced by line_parsing().

◆ get_export()

void get_export ( const char * str)

Definition at line 3662 of file lp.c.

3662 {
3663
3664 /* INSTRUCTION: EXPORT */
3665 /* - export identifiers mandatory, unsigned */
3666
3667 long d;
3668
3669 if (data_flag[depth]) {
3670 print_error_location("data", mline, mfile);
3671 (void) fprintf(STDERR, " instruction 'export' is not allowed in a data cell file\n");
3672 return;
3673 }
3674 if (0L != width) {
3675 print_error_location("export", mline, mfile);
3676 (void) fprintf(STDERR, " export declaration does not support a width limit\n");
3677 /* parsing of instruction may continue */
3678 }
3679 if (ISEMPTY(str)) {
3680 print_error_location("export", mline, mfile);
3681 (void) fprintf(STDERR, " export variable or node is missing\n");
3682 return;
3683 }
3684 strcpy_alloc(&(Export_List[Num_Exports].name), str, mline, mfile);
3685 for (d = 0L; d < MAXDEPTH; d++) {
3686 Export_List[Num_Exports].mline[d] = mline[d]; /* record line for identification */
3687 Export_List[Num_Exports].mfile[d] = mfile[d]; /* record file for identification */
3688 }
3689 increment_export_number("export");
3690 Export_Flag = true;
3691 return;
3692}
void increment_export_number(const char *kind)
Definition id.c:280
EXTERN EXPORT_TYPE Export_List[31L]
Definition napa.h:956
EXTERN int Export_Flag
Definition napa.h:855
EXTERN long Num_Exports
Definition napa.h:813

References Export_Flag, Export_List, increment_export_number(), ISEMPTY, MAXDEPTH, Num_Exports, print_error_location(), STDERR, and strcpy_alloc().

Referenced by get_var(), and line_parsing().

◆ get_format()

void get_format ( char * str)

Definition at line 3907 of file lp.c.

3907 {
3908
3909 /* INSTRUCTION: FORMAT */
3910 /* - (analog) output_format mandatory */
3911 /* - (digital) output_format mandatory */
3912 /* - (string) output_format mandatory */
3913
3914 char tok1[STRLENGTH] = {'\0'};
3915 char brc[3] = {'\0'};
3916
3917 if (data_flag[depth]) {
3918 print_error_location("data", mline, mfile);
3919 (void) fprintf(STDERR, " instruction 'format' is not allowed in a data cell file\n");
3920 return;
3921 }
3922 if (0L != width) {
3923 print_warning_location("format", mline, mfile);
3924 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width );
3925 }
3926 if (ISEMPTY(str)) {
3927 print_error_location("format", mline, mfile);
3928 (void) fprintf(STDERR, " format parameters are missing\n");
3929 return;
3930 }
3931 str = get_token_between_braces(str, brc, tok1);
3932 if ((0 != strcmp(brc, "()")) || (ISEMPTY(tok1))) {
3933 print_error_location("format", mline, mfile);
3934 (void) fprintf(STDERR, " format type is missing. Expecting (analog), (digital) or (string)\n");
3935 return;
3936 }
3937 if (0 == strncmp(tok1, "analog", (size_t) 6)) {
3938 read_doub_format(str);
3939 return;
3940 }
3941 if (0 == strcmp(tok1, "digital")) {
3942 read_int_format(str);
3943 return;
3944 }
3945 if (0 == strncmp(tok1, "hex", (size_t) 3)) {
3946 read_hex_format(str);
3947 return;
3948 }
3949 if (0 == strcmp(tok1, "string")) {
3950 read_str_format(str);
3951 return;
3952 }
3953 print_error_location("format", mline, mfile);
3954 (void) fprintf(STDERR, " format type is not correct. Expecting (analog), (digital) or (string)\n");
3955 return;
3956}
void read_int_format(char *str)
Definition lp.c:3999
void read_hex_format(char *str)
Definition lp.c:4039
void read_str_format(char *str)
Definition lp.c:4079
void read_doub_format(char *str)
Definition lp.c:3959

References get_token_between_braces(), ISEMPTY, print_error_location(), print_warning_location(), read_doub_format(), read_hex_format(), read_int_format(), read_str_format(), STDERR, and STRLENGTH.

Referenced by line_parsing().

◆ get_fs_ts()

void get_fs_ts ( char * str,
long fs1ts0 )

Definition at line 3293 of file lp.c.

3293 {
3294
3295 /* INSTRUCTION: FS or TS (exclusive usage) */
3296 /* - sampling optional, double > 0.0 */
3297 /* fs/ts instruction must be unique */
3298
3299 char tok[STRLENGTH] = {'\0'};
3300 char sgn[2] = {'\0'};
3301 char tag[3] = {'\0'};
3302 long d;
3303
3304 if (Fs_Flag) { /* fs is already defined */
3305 print_error_location(tag, mline, mfile);
3306 (void) fprintf(STDERR, " collision with a previous definition of the sampling frequency\n");
3308 return;
3309 }
3310 if (Ts_Flag) { /* ts is already defined */
3311 print_error_location(tag, mline, mfile);
3312 (void) fprintf(STDERR, " collision with a previous definition of the sampling period\n");
3314 return;
3315 }
3316 if (!Periodic_Flag) { /* sampling is already defined */
3317 print_error_location(tag, mline, mfile);
3318 (void) fprintf(STDERR, " collision with a precious definition of a sampling formula\n");
3320 return;
3321 }
3322 if (0L == fs1ts0) { /* input is a sampling period */
3323 (void) strcpy(tag, "ts");
3324 Fs_Flag = false;
3325 Ts_Flag = true;
3326 } else { /* input is a sampling frequency */
3327 (void) strcpy(tag, "fs");
3328 Fs_Flag = true;
3329 Ts_Flag = false;
3330 }
3331 if (data_flag[depth]) {
3332 print_error_location("data", mline, mfile);
3333 (void) fprintf(STDERR, " instructions '%s' is not allowed in a data cell file\n", tag);
3334 return;
3335 }
3336 if (0L != width) {
3337 print_warning_location(tag, mline, mfile);
3338 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width);
3339 }
3340 str = get_sign_and_token(str, sgn, tok);
3341 if (ISEMPTY(tok)) { /* no value means 1.0 by default */
3342 (void) strcpy(tok, "1.0");
3343 }
3344 if (ANALOG_DATA_TYPE != constant_type(tok)) {
3345 print_error_location(tag, mline, mfile);
3346 (void) fprintf(STDERR, " sampling <%s> must be an analog type constant\n", tok);
3347 Sampling_List.frequency = 1.0;
3348 return;
3349 }
3350 if (ISNOTEMPTY(sgn)) {
3351 print_error_location(tag, mline, mfile);
3352 (void) fprintf(STDERR, " no sign expected in front of the sampling");
3353 if (0L == fs1ts0) {
3354 (void) fprintf(STDERR, " period\n"); /* input is a sampling period */
3355 } else {
3356 (void) fprintf(STDERR, " frequency\n"); /* input is a sampling frequency */
3357 }
3358 Sampling_List.frequency = 1.0;
3359 return;
3360 }
3361 if (ISNOTEMPTY(str)) {
3362 print_error_location(tag, mline, mfile);
3363 (void) fprintf(STDERR, " spurious text <%s> appears at the end of sampling definition\n", str);
3364 }
3365 if (0L == fs1ts0) { /* input is a sampling period */
3366 if (1 != sscanf(tok, "%lf", &(Sampling_List.period))) {
3367 print_error_location(tag, mline, mfile);
3368 (void) fprintf(STDERR, " sampling period '%s' is not a well-formed positive C number <%s>\n", tag, tok);
3369 Sampling_List.period = 1.0;
3370 return;
3371 }
3372 if (0.0 >= Sampling_List.period) {
3373 print_error_location(tag, mline, mfile);
3374 (void) fprintf(STDERR, " sampling period must be strictly positive\n");
3375 Sampling_List.period = 1.0;
3376 return;
3377 }
3378 Sampling_List.frequency = 1.0 / Sampling_List.period;
3379 } else { /* input is a sampling frequency */
3380 if (1 != sscanf(tok, "%lf", &(Sampling_List.frequency))) {
3381 print_error_location(tag, mline, mfile);
3382 (void) fprintf(STDERR, " sampling frequency '%s' is not a well-formed positive C number <%s>\n", tag, tok);
3383 Sampling_List.frequency = 1.0;
3384 return;
3385 }
3386 if (0.0 >= Sampling_List.frequency) {
3387 print_error_location(tag, mline, mfile);
3388 (void) fprintf(STDERR, " sampling frequency must be strictly positive\n");
3389 Sampling_List.frequency = 1.0;
3390 return;
3391 }
3392 Sampling_List.period = 1.0 / Sampling_List.frequency;
3393 }
3394 for (d = 0L; d < MAXDEPTH; d++) {
3395 Sampling_List.mline[d] = mline[d]; /* record line for identification */
3396 Sampling_List.mfile[d] = mfile[d]; /* record line for identification */
3397 }
3398 return;
3399}
EXTERN int Ts_Flag
Definition napa.h:884
EXTERN int Fs_Flag
Definition napa.h:856
EXTERN SAMPLING_TYPE Sampling_List
Definition napa.h:978
EXTERN int Periodic_Flag
Definition napa.h:873

References ANALOG_DATA_TYPE, constant_type(), Fs_Flag, get_sign_and_token(), ISEMPTY, ISNOTEMPTY, MAXDEPTH, Periodic_Flag, print_error_location(), print_location(), print_warning_location(), Sampling_List, STDERR, STRLENGTH, and Ts_Flag.

Referenced by line_parsing().

◆ get_gateway()

void get_gateway ( char * str)

Definition at line 2860 of file lp.c.

2860 {
2861
2862 /* INSTRUCTION: GATEWAY */
2863 /* - countdown initialization optional, integer > 0 */
2864 /* Gateway instruction must be unique */
2865
2866 char tok1[STRLENGTH] = {'\0'};
2867 char tok2[STRLENGTH] = {'\0'};
2868 char sgn[2] = {'\0'};
2869
2870 if (data_flag[depth]) {
2871 print_error_location("data", mline, mfile);
2872 (void) fprintf(STDERR, " instruction 'gateway' is not allowed in a data cell file\n");
2873 return;
2874 }
2875 if (0L != width) {
2876 print_warning_location("gateway", mline, mfile);
2877 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width);
2878 }
2879 if (Gateway_Flag) {
2880 print_error_location("gateway", mline, mfile);
2881 (void) fprintf(STDERR, " only one gateway is allowed in a simulation\n");
2882 return;
2883 }
2884 (void) get_sign_and_token(str, sgn, tok1);
2885 (void) snprintf(tok2, (size_t) (STRLENGTH-1L), "%s%s", sgn, tok1); /* signed integer value */
2886 if (ISNOTEMPTY(tok2)) {
2887 if (1 != sscanf(tok2, "%li", &(Gateway_List.counter))) {
2888 print_error_location("gateway", mline, mfile);
2889 (void) fprintf(STDERR, " counter is not a well-formed positive C integer <%s>\n", tok2);
2890 return;
2891 }
2892 if (0L > Gateway_List.counter) {
2893 print_error_location("gateway", mline, mfile);
2894 (void) fprintf(STDERR, " counter must be a positive number\n");
2895 return;
2896 }
2897 } else {
2898 Gateway_List.counter = 0L; /* default value is zero */
2899 }
2900 Gateway_List.segment = Num_Segments - 1L; /* record segment level */
2901 Segment_List[Num_Segments-1L].used3 = true;
2902 Gateway_Flag = true;
2903 return;
2904}
EXTERN GATEWAY_TYPE Gateway_List
Definition napa.h:973
EXTERN int Gateway_Flag
Definition napa.h:859

References Gateway_Flag, Gateway_List, get_sign_and_token(), ISNOTEMPTY, Num_Segments, print_error_location(), print_warning_location(), Segment_List, STDERR, and STRLENGTH.

Referenced by line_parsing().

◆ get_header()

void get_header ( char * str)

Definition at line 1577 of file lp.c.

1577 {
1578
1579 /* INSTRUCTION: HEADER */
1580 /* - file pathname mandatory */
1581 /* - qualifier expand, noexpand optional */
1582
1583 char tok1[STRLENGTH] = {'\0'};
1584 char tok2[STRLENGTH] = {'\0'};
1585 char tok3[STRLENGTH] = {'\0'};
1586 char tok4[STRLENGTH] = {'\0'};
1587 char brc[3] = {'\0'};
1588 long d, i;
1589 str = get_token_between_braces(str, brc, tok3); /* process following NAPA file system */
1590 build_pathname(brc, tok3, Header_Lib_Name, mline, mfile);
1591 (void) strcpy(tok4, Cur_Lib_Name[depth]); /* do not modify Cur_Lib_Name[] */
1592 extract_directory(tok4, tok3, depth); /* there is no record of new pathname */
1593 (void) snprintf(tok1, (size_t) (STRLENGTH-1L), "%s%s", tok4, tok3);
1594 if (0L != width) {
1595 print_warning_location("header", mline, mfile);
1596 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width);
1597 }
1598 if (ISEMPTY(tok1)) {
1599 print_error_location("header", mline, mfile);
1600 (void) fprintf(STDERR, " file name is missing\n");
1601 return;
1602 }
1603 if (0L == Num_Headers) { /* 1st header file must be "napa.hdr" */
1604 (void) strcpy(tok2, tok1);
1605 drop_pathname(tok2); /* remove pathname if any */
1606 if ((char*) NULL == strstr(tok2, ".")) { /* complete file name with hdr ext. */
1607 (void) strcat(tok2, ".hdr");
1608 }
1609 if (((0 != strncmp(tok2, "napa", (size_t) 4))
1610 || (0 != strcmp(tok2 + ((int) strlen(tok2)) - 4, ".hdr"))) && (0 == Error_Flag)) {
1611 print_error_location("header", mline, mfile);
1612 (void) fprintf(STDERR, " Very first header in netlist must be the header file <napa.hdr>.\n");
1613 (void) fprintf(STDERR, " This header contains essential informations for compilation.\n");
1614 (void) fprintf(STDERR, " If needed, it can be replaced by a customized version,\n");
1615 (void) fprintf(STDERR, " file name must be prefixed by <napa> and suffixed with <.hdr>\n");
1616 /* parsing of instruction may continue */
1617 }
1618 }
1619 str = get_token_between_braces(str, brc, tok2); /* optional expand/noexpand token */
1620 if (ISEMPTY(tok2)) {
1621 (void) strcpy(tok2, "noexpand"); /* default value is 'noexpand' */
1622 }
1623 if ((0 != strcmp(tok2, "expand")) && (0 != strcmp(tok2, "noexpand"))) {
1624 replace_dollar(tok2);
1625 print_error_location("header", mline, mfile);
1626 (void) fprintf(STDERR, " (%s) is not a valid header qualifier\n\n", tok2);
1627 (void) fprintf(STDERR, " valid qualifiers are:\n");
1628 (void) fprintf(STDERR, " (noexpand)\n");
1629 (void) fprintf(STDERR, " (expand)\n");
1630 (void) strcpy(tok2, "noexpand");
1631 return;
1632 }
1633 if (ISNOTEMPTY(str)) {
1634 print_error_location("header", mline, mfile);
1635 (void) fprintf(STDERR, " invalid string <%s> after header qualifier (%s)", str, tok2);
1636 return;
1637 }
1638 if ((char*) NULL == strstr(tok1, ".")) { /* complete file name with hdr extension */
1639 (void) strcat(tok1, ".hdr");
1640 }
1641 simplify_pathname(tok1);
1642 for (i = 0L; i < Num_Headers; i++) { /* scan headers already registered */
1643 if (0 == fnstrcmp(Header_List[i].fname, tok1)) {
1644 if (0 != strcmp(Header_List[i].option, tok2)) {
1645 strcpy_realloc(&(Header_List[i].option),"expand", mline, mfile); /* at least one instantiation is asking for expand */
1646 }
1647 return; /* not necessary to register twice, exit function */
1648 }
1649 }
1650 strcpy_alloc(&(Header_List[Num_Headers].fname), tok1, mline, mfile); /* header pathname */
1651 strcpy_alloc(&(Header_List[Num_Headers].option), tok2, mline, mfile); /* option */
1652 for (d = 0L; d < MAXDEPTH; d++) {
1653 Header_List[Num_Headers].mline[d] = mline[d]; /* record line for identification */
1654 Header_List[Num_Headers].mfile[d] = mfile[d]; /* record file for identification */
1655 }
1656 increment_header_number("header");
1657 return;
1658}
void strcpy_realloc(char **dest, const char *sour, const unsigned long *mlin, const unsigned long *mfil)
Definition id.c:129
void increment_header_number(const char *kind)
Definition id.c:347
EXTERN int Error_Flag
Definition napa.h:853
EXTERN long Num_Headers
Definition napa.h:818
EXTERN HEADER_TYPE Header_List[63L]
Definition napa.h:959
EXTERN char * Header_Lib_Name
Definition napa.h:914
void replace_dollar(char *tok)
Definition tk.c:1713
void drop_pathname(char *pnam)
Definition tk.c:1526

References build_pathname(), Cur_Lib_Name, drop_pathname(), Error_Flag, extract_directory(), fnstrcmp(), get_token_between_braces(), Header_Lib_Name, Header_List, increment_header_number(), ISEMPTY, ISNOTEMPTY, MAXDEPTH, Num_Headers, print_error_location(), print_warning_location(), replace_dollar(), simplify_pathname(), STDERR, strcpy_alloc(), strcpy_realloc(), and STRLENGTH.

Referenced by line_parsing().

◆ get_init()

void get_init ( char * str)

Definition at line 2634 of file lp.c.

2634 {
2635
2636 /* INSTRUCTION: INIT */
2637 /* - parameters mandatory */
2638
2639 /* Parameters are stored for further processing */
2640
2641 long d;
2642 char buf[STRLENGTH] = {'\0'};
2643 if (0L != width) {
2644 print_error_location("init", mline, mfile);
2645 (void) fprintf(STDERR, " C expression cannot be width limited\n");
2646 /* parsing of instruction may continue */
2647 }
2648 if (ISEMPTY(str)) {
2649 print_error_location("init", mline, mfile);
2650 (void) fprintf(STDERR, " init expression is missing\n");
2651 return;
2652 }
2653 (void) snprintf(buf, (size_t) 31, "$init$_%ld", Num_Inits);
2654 increment_init_number("init");
2655 strcpy_alloc(&(Var_List[Num_Vars].name1), buf, mline, mfile); /* keyword: $init$_.. */
2656 strcpy_alloc(&(Var_List[Num_Vars].name2), buf, mline, mfile); /* copy of name */
2657 Var_List[Num_Vars].aliased = false; /* not aliased */
2658 clean_parentheses(str);
2659 resolve_pathnames(str, depth); /* resolve pathname using conventions */
2660 strcpy_alloc(&(Var_List[Num_Vars].value), str, mline, mfile); /* unprocessed value */
2661 strcpy_alloc(&(Var_List[Num_Vars].comment), "", mline, mfile); /* currently empty */
2662 Var_List[Num_Vars].type = UNKNOWN_TYPE; /* will be defined later */
2663 Var_List[Num_Vars].used = true; /* don't care */
2664 Var_List[Num_Vars].declare = UNKNOWN_TYPE;
2665 Var_List[Num_Vars].external = false;
2666 Var_List[Num_Vars].event = false;
2667 Var_List[Num_Vars].determined = true;
2668 Var_List[Num_Vars].constant = false; /* don't care */
2669 Var_List[Num_Vars].segment = Num_Segments - 1L; /* record segment level */
2670 for (d = 0L; d < MAXDEPTH; d++) {
2671 Var_List[Num_Vars].mline[d] = mline[d]; /* record line for identification */
2672 Var_List[Num_Vars].mfile[d] = mfile[d]; /* record file for identification */
2673 }
2674 increment_var_number("init");
2675 return;
2676}

References clean_parentheses(), increment_init_number(), increment_var_number(), ISEMPTY, MAXDEPTH, Num_Inits, Num_Segments, Num_Vars, print_error_location(), resolve_pathnames(), STDERR, strcpy_alloc(), STRLENGTH, UNKNOWN_TYPE, and Var_List.

Referenced by line_parsing().

◆ get_inject()

void get_inject ( char * str)

Definition at line 2978 of file lp.c.

2978 {
2979
2980 /* INSTRUCTION: INJECT */
2981 /* - node name unsigned, mandatory, defined */
2982 /* - C expression mandatory, no self-reference */
2983
2984 /* Expression is stored for further processing */
2985
2986 char tok1[STRLENGTH] = {'\0'};
2987 char sgn[2] = {'\0'};
2988 long d;
2989 double dtemp;
2990
2991 if (data_flag[depth]) {
2992 print_error_location("inject", mline, mfile);
2993 (void) fprintf(STDERR, " instruction 'inject' is not allowed in a data cell file\n");
2994 return;
2995 }
2996 str = get_sign_and_token(str, sgn, tok1); /* node_name */
2997 if (0L != width) {
2998 print_error_location("inject", mline, mfile);
2999 (void) fprintf(STDERR, " width limitation is not allowed\n");
3000 /* parsing of instruction may continue */
3001 }
3002 if (!is_an_identifier(tok1)) {
3003 print_error_location("inject", mline, mfile);
3004 (void) fprintf(STDERR, " node name <%s> is not a NAPA identifier\n", tok1);
3005 return;
3006 }
3007 if (ISEMPTY(tok1)) {
3008 print_error_location("inject", mline, mfile);
3009 (void) fprintf(STDERR, " node name is missing\n");
3010 return;
3011 }
3012 if (ISNOTEMPTY(sgn)) {
3013 print_error_location("inject", mline, mfile);
3014 (void) fprintf(STDERR, " no sign expected in front of the node identifier <%s>\n", tok1);
3015 /* parsing of instruction may continue */
3016 }
3017 if (ISEMPTY(str)) {
3018 print_error_location("inject", mline, mfile);
3019 (void) fprintf(STDERR, " inject value is missing\n");
3020 return;
3021 }
3022 if ((1 == sscanf(str, "%lf", &dtemp)) && ISSMALL(dtemp)) {
3023 return; /* nothing is injected ! */
3024 }
3025 strcpy_alloc(&(Inject_List[Num_Injects].name), tok1, mline, mfile);
3026 clean_parentheses(str);
3027 resolve_pathnames(str, depth); /* resolve pathname using conventions */
3028 strcpy_alloc(&(Inject_List[Num_Injects].value), str, mline, mfile); /* unprocessed */
3029 for (d = 0L; d < MAXDEPTH; d++) {
3030 Inject_List[Num_Injects].mline[d] = mline[d]; /* record line for identification */
3031 Inject_List[Num_Injects].mfile[d] = mfile[d]; /* record file for identification */
3032 }
3033 increment_inject_number("inject");
3034 Inject_Flag = true;
3035 return;
3036}
void increment_inject_number(const char *kind)
Definition id.c:373
EXTERN long Num_Injects
Definition napa.h:820
#define ISSMALL(x)
Definition napa.h:386
EXTERN INJECT_TYPE Inject_List[63L]
Definition napa.h:960
EXTERN int Inject_Flag
Definition napa.h:861

References clean_parentheses(), get_sign_and_token(), increment_inject_number(), Inject_Flag, Inject_List, is_an_identifier(), ISEMPTY, ISNOTEMPTY, ISSMALL, MAXDEPTH, Num_Injects, print_error_location(), resolve_pathnames(), STDERR, strcpy_alloc(), and STRLENGTH.

Referenced by line_parsing().

◆ get_input()

void get_input ( char * str)

Definition at line 2291 of file lp.c.

2291 {
2292
2293 /* INSTRUCTION: INPUT */
2294 /* - stream name mandatory */
2295 /* - input list mandatory */
2296
2297 /* Stream and input list are stored for further processing */
2298
2299 char tok1[STRLENGTH] = {'\0'};
2300 char tok2[STRLENGTH] = {'\0'};
2301 long d;
2302 int i;
2303
2304 if (data_flag[depth]) {
2305 print_error_location("data", mline, mfile);
2306 (void) fprintf(STDERR, " instruction 'input' is not allowed in a data cell file\n");
2307 return;
2308 }
2309 if (0L != width) {
2310 print_error_location("input", mline, mfile);
2311 (void) fprintf(STDERR, " input cannot be width limited\n");
2312 /* parsing of instruction may continue */
2313 }
2314 str = get_token(str, tok1, true);
2315 if (ISEMPTY(tok1)) {
2316 print_error_location("input", mline, mfile);
2317 (void) fprintf(STDERR, " stream input is missing\n");
2318 return;
2319 }
2320 if (ISEMPTY(str)) {
2321 print_error_location("input", mline, mfile);
2322 (void) fprintf(STDERR, " list of variables is missing\n");
2323 return;
2324 }
2325 resolve_pathnames(tok1, depth); /* resolve pathname using conventions ` */
2326 (void) get_token(tok1, tok2, false);
2327 simplify_pathname(tok2);
2328 for (i = 0; i < Num_IOs; i++) {
2329 if (0 == fnstrcmp(IO_List[i].fname, tok2)) {
2330 print_error_location("output", mline, mfile);
2331 (void) fprintf(STDERR, " collision between I/O streams, <%s> is already defined", tok2);
2332 if (INPUT_TYPE == IO_List[i].type) {
2333 (void) fprintf(STDERR, " as input\n");
2334 }
2335 if (OUTPUT_TYPE == IO_List[i].type) {
2336 (void) fprintf(STDERR, " as output\n");
2337 }
2338 }
2339 }
2340 if (Dump_Flag) {
2341 if (0 == fnstrcmp(Dump_List.fname, tok2)) {
2342 print_error_location("input", mline, mfile);
2343 (void) fprintf(STDERR, " collision with I/O streams, <%s> is already defined as a dump file", tok2);
2344 }
2345 }
2346 strcpy_alloc(&(IO_List[Num_IOs].fname), tok2, mline, mfile); /* in_filename without "" */
2347 strcpy_alloc(&(IO_List[Num_IOs].element), str, mline, mfile); /* unprocessed I/O list of elements */
2348 IO_List[Num_IOs].segment = 0L; /* to avoid side effect, segment 0 ! */
2349 IO_List[Num_IOs].type = INPUT_TYPE; /* record io type */
2350 IO_List[Num_IOs].event = false; /* not used */
2351 Segment_List[Num_Segments-1L].used1 = true;
2352 for (d = 0L; d < MAXDEPTH; d++) {
2353 IO_List[Num_IOs].mline[d] = mline[d]; /* record line for identification */
2354 IO_List[Num_IOs].mfile[d] = mfile[d]; /* record file for identification */
2355 }
2356 Input_Flag = true;
2357 increment_IO_number("input");
2358 return;
2359}
void increment_IO_number(const char *kind)
Definition id.c:399
EXTERN int Input_Flag
Definition napa.h:862

References Dump_Flag, Dump_List, fnstrcmp(), get_token(), increment_IO_number(), Input_Flag, INPUT_TYPE, IO_List, ISEMPTY, MAXDEPTH, Num_IOs, Num_Segments, OUTPUT_TYPE, print_error_location(), resolve_pathnames(), Segment_List, simplify_pathname(), STDERR, strcpy_alloc(), and STRLENGTH.

Referenced by line_parsing().

◆ get_interlude()

void get_interlude ( char * str)

Definition at line 3452 of file lp.c.

3452 {
3453
3454 /* INSTRUCTION: INTERLUDE */
3455 /* - interlude value integer >= 0 */
3456 /* - interlude min max integers > 0 */
3457 /* interlude instruction should be unique */
3458
3459 char tok1[STRLENGTH] = {'\0'};
3460 char tok2[STRLENGTH] = {'\0'};
3461 char tok3[STRLENGTH] = {'\0'};
3462 char tok4[STRLENGTH] = {'\0'};
3463 char tok5[STRLENGTH] = {'\0'};
3464 char tok6[STRLENGTH] = {'\0'};
3465 char sgn[2] = {'\0'};
3466 long d;
3467 if (data_flag[depth]) {
3468 print_error_location("data", mline, mfile);
3469 (void) fprintf(STDERR, " instruction 'interlude' is not allowed in a data cell file\n");
3470 return;
3471 }
3472 if (0L != width) {
3473 print_warning_location("interlude", mline, mfile);
3474 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width);
3475 }
3476 if (Interlude_Flag1) {
3477 print_error_location("interlude", mline, mfile);
3478 (void) fprintf(STDERR, " overwriting a previous definition of interlude\n");
3479 }
3480 if (ISEMPTY(str)) {
3481 print_error_location("interlude", mline, mfile);
3482 (void) fprintf(STDERR, " waiting for a value or for min and max values\n");
3483 return;
3484 }
3485 str = get_sign_and_token(str, sgn, tok1);
3486 (void) snprintf(tok2, (size_t) (STRLENGTH-1L), "%s%s", sgn, tok1); /* signed integer for value or for min */
3487 Interlude_Flag1 = true;
3488 if (0L < LENGTH(str)) {
3489 str = get_sign_and_token(str, sgn, tok3);
3490 Interlude_Flag2 = true;
3491 (void) snprintf(tok4, (size_t) (STRLENGTH-1L), "%s%s", sgn, tok3); /* signed integer for max */
3492 } else {
3493 Interlude_Flag2 = false;
3494 }
3495 if (0L < LENGTH(str)) {
3496 str = get_sign_and_token(str, sgn, tok5);
3497 Interlude_Flag3 = true;
3498 (void) snprintf(tok6, (size_t) (STRLENGTH-1L), "%s%s", sgn, tok5); /* signed integer for max */
3499 } else {
3500 Interlude_Flag3 = false;
3501 }
3502 if (ISNOTEMPTY(str)) {
3503 print_error_location("interlude", mline, mfile);
3504 (void) fprintf(STDERR, " spurious text <%s> appears at the end of the instruction\n", str);
3505 Interlude_Flag1 = false;
3506 }
3507 if (1 != sscanf(tok2, "%li", &Interlude_List.number1)) {
3508 print_error_location("interlude", mline, mfile);
3509 if (!Interlude_Flag2) {
3510 (void) fprintf(STDERR, " the range value is not a well-formed positive C integer <%s>\n", tok2);
3511 } else {
3512 (void) fprintf(STDERR, " the min value is not a well-formed positive C integer <%s>\n", tok2);
3513 }
3514 Interlude_Flag1 = false;
3515 Interlude_List.number1 = 0L;
3516 return;
3517 }
3518 if (0L > Interlude_List.number1) {
3519 print_error_location("interlude", mline, mfile);
3520 if (!Interlude_Flag2) {
3521 (void) fprintf(STDERR, " the range value is not a positive integer <%ld>\n", Interlude_List.number1);
3522 } else {
3523 (void) fprintf(STDERR, " the min value is not a positive integer <%ld>\n", Interlude_List.number1);
3524 }
3525 Interlude_Flag1 = false;
3526 Interlude_List.number1 = 0L;
3527 }
3528 if (Interlude_Flag2) {
3529 if (1 != sscanf(tok4, "%li", &Interlude_List.number2)) {
3530 print_error_location("interlude", mline, mfile);
3531 (void) fprintf(STDERR, " the max value is not a well-formed positive C integer <%s>\n", tok4);
3532 Interlude_Flag1 = false;
3533 Interlude_Flag2 = false;
3534 Interlude_List.number1 = 0L;
3535 Interlude_List.number2 = 0L;
3536 return;
3537 }
3538 if (0L >= Interlude_List.number2) {
3539 print_error_location("interlude", mline, mfile);
3540 (void) fprintf(STDERR, " the max value is not a strictly positive integer <%ld>\n", Interlude_List.number2);
3541 Interlude_Flag1 = false;
3542 Interlude_Flag2 = false;
3543 Interlude_List.number1 = 0L;
3544 Interlude_List.number2 = 0L;
3545 }
3546 if (Interlude_List.number1 > Interlude_List.number2) {
3547 print_warning_location("interlude", mline, mfile);
3548 (void) fprintf(STDERR, " the max value <%ld> cannot be smaller than the min value <%ld> and will be ignored\n",
3549 Interlude_List.number2, Interlude_List.number1);
3550 Interlude_Flag2 = false;
3551 Interlude_List.number2 = Interlude_List.number1;
3552 }
3553 } else {
3554 Interlude_List.number2 = Interlude_List.number1;
3555 }
3556 if (Interlude_Flag3) {
3557 if (1 != sscanf(tok6, "%li", &Interlude_List.number3)) {
3558 print_error_location("interlude", mline, mfile);
3559 (void) fprintf(STDERR, " the resolution value is not a well-formed positive C integer <%s>\n", tok6);
3560 Interlude_Flag1 = false;
3561 Interlude_Flag2 = false;
3562 Interlude_Flag3 = false;
3563 Interlude_List.number1 = 0L;
3564 Interlude_List.number2 = 0L;
3565 Interlude_List.number3 = 0L;
3566 return;
3567 } else {
3568 if (Interlude_List.number3 > (2L * (Interlude_List.number2 - Interlude_List.number1))) {
3569 print_warning_location("interlude", mline, mfile);
3570 (void) fprintf(STDERR, " the resolution <%ld>, being too small, will be reset to 0\n", Interlude_List.number3);
3571 Interlude_Flag3 = false;
3572 Interlude_List.number3 = 0L;
3573 }
3574 }
3575 }
3576 for (d = 0L; d < MAXDEPTH; d++) {
3577 Interlude_List.mline[d] = mline[d]; /* record line for identification */
3578 Interlude_List.mfile[d] = mfile[d]; /* record file for identification */
3579 }
3580 return;
3581}
EXTERN int Interlude_Flag3
Definition napa.h:870
EXTERN INTERLUDE_TYPE Interlude_List
Definition napa.h:974
EXTERN int Interlude_Flag1
Definition napa.h:868
EXTERN int Interlude_Flag2
Definition napa.h:869

References get_sign_and_token(), Interlude_Flag1, Interlude_Flag2, Interlude_Flag3, Interlude_List, ISEMPTY, ISNOTEMPTY, LENGTH, MAXDEPTH, print_error_location(), print_warning_location(), STDERR, and STRLENGTH.

Referenced by line_parsing().

◆ get_interpolate()

void get_interpolate ( char * str)

Definition at line 1940 of file lp.c.

1940 {
1941
1942 /* INSTRUCTION: INTERPOLATE */
1943 /* - "fs" optional */
1944 /* - interpolation value mandatory, integer > 0 */
1945
1946 char tok1[STRLENGTH] = {'\0'};
1947 char tok2[STRLENGTH] = {'\0'};
1948 char sgn[2] = {'\0'};
1949 long ltemp;
1950 long ref;
1951 long d, v;
1952
1953 if (data_flag[depth]) {
1954 print_error_location("data", mline, mfile);
1955 (void) fprintf(STDERR, " instruction 'interpolate' is not allowed in a data cell file\n");
1957 }
1958 if (0L != width) {
1959 print_warning_location("interpolate", mline, mfile);
1960 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width);
1961 }
1962 str = get_sign_and_token(str, sgn, tok1);
1963 if (ISEMPTY(tok1)) {
1964 print_error_location("interpolate", mline, mfile);
1965 (void) fprintf(STDERR, " interpolation value is missing\n");
1967 }
1968 if (0 == strcmp(tok1, "fs")) {
1969 ref = 1L; /* reference: relative to previous segment */
1970 str = get_sign_and_token(str, sgn, tok1);
1971 Drop_Flag = false; /* reset Drop_Flag as it is an absolute reference */
1972 } else { /* reference: absolute */
1973 ref = 0L;
1974 }
1975 (void) snprintf(tok2, (size_t) (STRLENGTH-1L), "%s%s", sgn, tok1); /* signed integer value */
1976 v = var_id(tok2);
1977 while (v != UNDEFINED) {
1978 (void) strcpy(tok2, Var_List[v].value);
1979 Var_List[v].used = true;
1980 v = var_id(tok2);
1981 }
1982 if (1 != sscanf(tok2, "%li", &(ltemp))) {
1983 print_error_location("interpolate", mline, mfile);
1984 (void) fprintf(STDERR, " rate is not a well-formed positive C integer <%s>,\n", tok2);
1985 (void) fprintf(STDERR, " if <%s> is a variable, it should be defined as a number before this instruction\n", tok2);
1987 }
1988 if (0L >= ltemp) {
1989 print_error_location("interpolate", mline, mfile);
1990 (void) fprintf(STDERR, " rate is not a positive integer <%s>\n", tok2);
1992 }
1993 Segment_List[Num_Segments].rate = (double) ltemp;
1994 Interpolate_Flag = true;
1996 Segment_List[Num_Segments].ref = ref;
1997 Segment_List[Num_Segments].offset = 0.0;
1998 Segment_List[Num_Segments].used1 = false;
1999 Segment_List[Num_Segments].used2 = false;
2000 Segment_List[Num_Segments].used3 = false;
2001 if (!Drop_Flag) { /* no drop instruction before */
2002 Segment_List[Num_Segments].periodic = true;
2003 } else {
2004 Segment_List[Num_Segments].periodic = false; /* periodic sampling not guaranteed */
2005 }
2006 for (d = 0L; d < MAXDEPTH; d++) {
2007 Segment_List[Num_Segments].mline[d] = mline[d];
2008 Segment_List[Num_Segments].mfile[d] = mfile[d];
2009 }
2010 increment_segment_number("interpolate");
2011 return;
2012}
EXTERN int Interpolate_Flag
Definition napa.h:863
#define INTERPOLATE_SEGMENT_TYPE
Definition napa.h:352

References Drop_Flag, get_sign_and_token(), increment_segment_number(), Interpolate_Flag, INTERPOLATE_SEGMENT_TYPE, ISEMPTY, MAXDEPTH, Num_Segments, print_error_banner_and_exit(), print_error_location(), print_warning_location(), Segment_List, STDERR, STRLENGTH, UNDEFINED, var_id(), and Var_List.

Referenced by line_parsing().

◆ get_load()

void get_load ( char * str)

Definition at line 4248 of file lp.c.

4248 {
4249
4250 /* INSTRUCTION: LOAD */
4251 /* - file pathname mandatory */
4252 /* Load instruction should be unique */
4253
4254 char buf[LINLENGTH] = {'\0'};
4255 char tok1[STRLENGTH] = {'\0'};
4256 char brc[3] = {'\0'};
4257 char *str1 = (char*) NULL;
4258 long v, d;
4259 (void) strcpy(buf, str);
4260 if (data_flag[depth]) {
4261 print_error_location("data", mline, mfile);
4262 (void) fprintf(STDERR, " instruction 'load' is not allowed in a data cell file\n" );
4263 return;
4264 }
4265 if (0L != width) {
4266 print_warning_location("load", mline, mfile);
4267 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width );
4268 }
4269 if (Load_Flag) {
4270 print_warning_location("load", mline, mfile);
4271 (void) fprintf(STDERR, " load already defined, previous definition is overwritten\n");
4272 }
4273 for (;;) {
4274 str = get_token(str, tok1, true);
4275 if (0 == strcmp(tok1, "when")) {
4276 print_error_location("load", mline, mfile);
4277 (void) fprintf(STDERR, " keyword 'when' is not allowed in a load statement\n" );
4278 }
4279 if (ISEMPTY(tok1)) {
4280 break;
4281 }
4282 }
4283 (void) strcpy(str, buf);
4284 str = get_token_between_braces(str, brc, tok1);
4285 if (ISEMPTY(tok1) || (0 != strcmp(brc, "\"\""))) {
4286 str = get_token(str, tok1, false);
4287 v = var_id(tok1);
4288 if ((UNDEFINED == v) || (STRING_DATA_TYPE != Var_List[v].type)) {
4289 mline[depth] = 0UL;
4290 print_error_location("load", mline, mfile);
4291 (void) fprintf(STDERR, " file name is missing or not correct: <%s>\n", tok1);
4292 return;
4293 }
4294 str1 = Var_List[v].value;
4295 (void) get_token_between_braces(str1, brc, tok1);
4296 }
4297 resolve_pathnames(tok1, depth); /* resolve pathname using conventions */
4298 simplify_pathname(tok1);
4299 strcpy_alloc(&(Load_List.fname), tok1, mline, mfile); /* load_File_Name */
4300 for (d = 0L; d < MAXDEPTH; d++) {
4301 Load_List.mline[d] = mline[d]; /* record line for identification */
4302 Load_List.mfile[d] = mfile[d]; /* record line for identification */
4303 }
4304 Load_Flag = true;
4305 return;
4306}
EXTERN int Load_Flag
Definition napa.h:865
EXTERN LOAD_TYPE Load_List
Definition napa.h:975

References get_token(), get_token_between_braces(), ISEMPTY, LINLENGTH, Load_Flag, Load_List, MAXDEPTH, print_error_location(), print_warning_location(), resolve_pathnames(), simplify_pathname(), STDERR, strcpy_alloc(), STRING_DATA_TYPE, STRLENGTH, UNDEFINED, var_id(), and Var_List.

Referenced by line_parsing().

◆ get_node()

char * get_node ( char * str,
char * nodnam,
long * pseudo )

Definition at line 600 of file lp.c.

600 {
601
602 /* INSTRUCTION: NODE */
603 /* - node name mandatory, unsigned, unique */
604 /* - node kind mandatory, unsigned */
605 /* - parameters mandatory, no self-reference */
606
607 /* Pseudo-nodes "cell" and "generator" are postprocessed immediately using 'process_cell()' or 'process_gen()' */
608 /* They are using the string output of get_node(). */
609
610 /* Pathnames of pseudo nodes have a special processing. For other nodes, the pathnames are immediately processed. */
611
612 /* Parameters of these nodes are stored in tables for further processing. */
613
614 char tok1[STRLENGTH] = {'\0'};
615 char tok2[STRLENGTH] = {'\0'};
616 char tok3[STRLENGTH] = {'\0'};
617 char tok4[LINLENGTH] = {'\0'};
618 char tok5[LINLENGTH] = {'\0'};
619 char tok6[LINLENGTH] = {'\0'};
620 char tok7[LINLENGTH] = {'\0'};
621 char tok8[LINLENGTH] = {'\0'};
622 char tok9[LINLENGTH] = {'\0'};
623 char tok10[LINLENGTH] = {'\0'};
624 char tok11[LINLENGTH] = {'\0'};
625 char brc[3] = {'\0'};
626 char sgn[2] = {'\0'};
627 char *t = (char*) NULL;
628 char *str1 = (char*) NULL;
629 char *str2 = (char*) NULL;
630 char *str3 = (char*) NULL;
631 char *str4 = (char*) NULL;
632 long kind;
633 long d, k, i;
634 long w;
635 long pn = UNKNOWN_KIND;
636 long n = 0L;
637 int flag;
638 flag = false;
639 if (data_flag[depth]) {
640 print_error_location("data", mline, mfile);
641 (void) fprintf(STDERR, " nodes definitions are not allowed in a data cell file\n");
642 return (char*) NULL;
643 }
644 str1 = get_token_between_braces(str, brc, tok2);
645 if (0 == strcmp(brc, "")) {
646 str = get_sign_and_token(str, sgn, tok1); /* signal name of the output of 'node' */
647 } else if (0 == strcmp(brc, "()")) {
648 flag = true; /* (...) means that we do not care of usage */
649 str = str1;
650 str1 = tok2;
651 str1 = get_sign_and_token(str1, sgn, tok1); /* signal name of the output of 'node' */
652 } else if (0 == strcmp(brc, "[]")) {
653 if (1 != sscanf(tok2, "%li", &w)) { /* [...] means that this is a nodeset */
654 w = 0L;
655 print_error_location("node", mline, mfile);
656 (void) fprintf(STDERR, " invalid width in declaration <node[%s]>\n", tok2);
657 return (char*) NULL;
658 }
659 if (0L >= w) {
660 w = 0L;
661 print_error_location("node", mline, mfile);
662 (void) fprintf(STDERR, " node width <%ld> must be strictly positive\n", w);
663 return (char*) NULL;
664 }
665 (void) strcpy(tok4, str1);
666 if (Expand_Flag) { /* netlist expansion requested */
667 n = (long) fprintf(STDOUT, "\n#* node[%ld] %s ", w, str1);
668 for (i = 0L; i < MAX(77L-n, 0L); i++) {
669 (void) fprintf(STDOUT, ".");
670 }
671 (void) fprintf(STDOUT, "...\n");
672 }
673 for (i = 0L; i < w; i++) { /* process node by node from the nodeset */
674 (void) strcpy(tok5, tok4);
675 str2 = tok5;
676 str2 = expand_nodeset(str2, i, w, mline, mfile);
677 if (Expand_Flag) { /* netlist expansion requested */
678 (void) fprintf(STDOUT, " node %s\n", str2); /* 4 spaces indent */
679 }
680 pseudonode = SET_KIND;
681 (void) get_node(str2, tok1, &pn);
682 if ((CELL_KIND == pn) || (GEN_KIND == pn)) {
683 print_error_location("node", mline, mfile);
684 (void) fprintf(STDERR, " a cell or a generator cannot be associated in a nodeset\n");
685 return (char*) NULL;
686 }
687 }
688 if (Expand_Flag) { /* netlist expansion requested */
689 (void) fprintf(STDOUT, "#* ");
690 for (i = 0L; i < MAX(n-5L, 72L); i++) {
691 (void) fprintf(STDOUT, ".");
692 }
693 (void) fprintf(STDOUT, "...\n\n");
694 }
695 return (char*) NULL;
696 } else {
697 print_error_location("node", mline, mfile);
698 (void) fprintf(STDERR, " brackets, if any, around node cannot be < %s > but parenthesis\n", brc);
699 return (char*) NULL;
700 }
701 if (ISEMPTY(tok1)) {
702 print_error_location("node", mline, mfile);
703 (void) fprintf(STDERR, " node name is missing\n");
704 return (char*) NULL;
705 }
706 if (!is_an_identifier(tok1)) {
707 print_error_location("syntax", mline, mfile);
708 (void) fprintf(STDERR, " node name <%s> is not a NAPA identifier\n", tok1);
709 return (char*) NULL;
710 }
711 if ((0 == strcmp(tok1, "One")) || (0 == strcmp(tok1, "Zero")) || (0 == strcmp(tok1, "Ground"))) {
712 print_error_location("node", mline, mfile);
713 (void) fprintf(STDERR, " automatic node <%s> cannot be redefined by user\n", tok1);
714 return (char*) NULL;
715 }
716 if ((char*) NULL != strchr(tok1, ':')) {
717 print_error_location("node", mline, mfile);
718 (void) fprintf(STDERR, " definition of node <%s> cannot include a bit field\n", tok1);
719 return (char*) NULL;
720 }
721 if (ISNOTEMPTY(sgn)) {
722 print_error_location("node", mline, mfile);
723 (void) fprintf(STDERR, " no sign expected in front of the node identifier <%s>\n", tok1);
724 /* parsing of instruction may continue */
725 }
726 i = node_id(tok1);
727 if (UNDEFINED != i) {
728 str3 = str;
729 str = get_sign_and_token(str, sgn, tok2); /* node kind */
730 kind = node_kind(tok2); /* node kind determination */
731 if ((GEN_KIND != kind) && (CELL_KIND != kind)) {
732 print_error_location("node", mline, mfile);
733 (void) fprintf(STDERR, " duplicate node definition, <%s> is already defined\n", tok1);
734 print_location(Node_List[i].mline, Node_List[i].mfile);
735 /* parsing of instruction may continue */
736 }
737 str = str3;
738 }
739 i = alias_id(tok1);
740 if (UNDEFINED != i) {
741 print_error_location("node", mline, mfile);
742 (void) fprintf(STDERR, " definition <%s> is colliding an alias defined\n", tok1);
743 print_location(Alias_List[i].mline, Alias_List[i].mfile);
744 /* parsing of instruction may continue */
745 }
746 i = var_id(tok1);
747 if (UNDEFINED != i) {
748 print_error_location("node", mline, mfile);
749 (void) fprintf(STDERR, " definition <%s> is colliding a variable defined\n", tok1);
750 print_location(Var_List[i].mline, Var_List[i].mfile);
751 /* parsing of instruction may continue */
752 }
753 i = record_id(tok1);
754 if (UNDEFINED != i) {
755 print_error_location("node", mline, mfile);
756 (void) fprintf(STDERR, " definition <%s> is colliding a record defined\n", tok1);
757 print_location(Record_List[i].mline, Record_List[i].mfile);
758 /* parsing of instrcution may continue */
759 }
760 i = array_id(tok1);
761 if (UNDEFINED != i) {
762 print_error_location("node", mline, mfile);
763 (void) fprintf(STDERR, " definition <%s> is colliding an array defined\n", tok1);
764 print_location(Array_List[i].mline, Array_List[i].mfile);
765 /* parsing of instruction may continue */
766 }
767 i = directive_id(tok1);
768 if (UNDEFINED != i) {
769 print_error_location("node", mline, mfile);
770 (void) fprintf(STDERR, " definition <%s> is colliding a directive defined\n", tok1);
771 print_location(Directive_List[i].mline, Directive_List[i].mfile);
772 /* parsing of instruction may continue */
773 }
774 if (0 == strcmp(tok1, "fs")) { /* not catched by is_a_keyword() function */
775 print_error_location("node", mline, mfile);
776 (void) fprintf(STDERR, " node identifier cannot be the <fs> identifier\n");
777 /* parsing of instruction may continue */
778 }
779 k = is_a_keyword(tok1);
780 if (ERROR == k) {
781 print_error_location("node", mline, mfile);
782 (void) fprintf(STDERR, " keyword <%s> cannot be used as node name\n", tok1);
783 /* parsing of instruction may continue */
784 }
785 if (WARNING == k) {
786 print_warning_location("node", mline, mfile);
787 (void) fprintf(STDERR, " keyword <%s> is not recommended to be used as node name\n", tok1);
788 }
789 str = get_sign_and_token(str, sgn, tok2); /* node kind */
790 if ((0 == strcmp(sgn, "+")) || (0 == strcmp(sgn, "-"))) {
791 print_error_location("syntax", mline, mfile);
792 (void) fprintf(STDERR, " no sign is expected before the node kind\n");
793 return (char*) NULL;
794 }
795 if (0 == strcmp(tok2, "[")) {
796 print_error_location("syntax", mline, mfile);
797 (void) fprintf(STDERR, " this is not a nodeset, brackets [] are not expected\n");
798 return (char*) NULL;
799 }
800 if (!is_an_identifier(tok2)) {
801 print_error_location("syntax", mline, mfile);
802 (void) fprintf(STDERR, " node kind <%s> is not a NAPA identifier\n", tok2);
803 process_node_error(tok2); /* help user for spelling error */
804 return (char*) NULL;
805 }
806 if (ISEMPTY(tok2)) {
807 print_error_location("node", mline, mfile);
808 (void) fprintf(STDERR, " node <%s>, node kind is missing\n", tok1);
809 return (char*) NULL;
810 }
811 kind = node_kind(tok2); /* node kind determination */
812 if (UNKNOWN_KIND == kind) {
813 print_error_location("node", mline, mfile);
814 (void) fprintf(STDERR, " unknown node kind <%s>\n", tok2);
815 process_node_kind_error(tok2); /* help user for spelling error */
816 return (char*) NULL;
817 }
818 if ((DUSER_KIND == kind) || (IUSER_KIND == kind) || (DTOOL_KIND == kind) || (ITOOL_KIND == kind)) {
819 str4 = str; /* process <fun()> as () will be destroyed below */
820 for (;;) {
821 str4 = get_function_identifier(str4, tok6, tok7);
822 if (ISNOTEMPTY(tok6)) {
823 (void) record_function_identifier(tok6, 0, mline, mfile);
824 }
825 if (ISEMPTY(str4)) {
826 break;
827 }
828 }
829 }
830 if ((ALGEBRA_KIND != kind) && (IALGEBRA_KIND != kind) && (DALGEBRA_KIND != kind)
831 && (DC_KIND != kind) && (TEST_KIND != kind) && (CONST_KIND != kind)) {
832 replace_parentheses(str); /* '(...)'->'$...' to avoid accident cell process */
833 }
834 if ((GEN_KIND == kind) || (CELL_KIND == kind)) { /* special process of pseudo-node */
835 *pseudo = kind; /* mark as pseudo-node */
836 (void) strcpy(nodnam, tok1); /* record node name back in 'nodnam' */
837 return str; /* jump to pseudo-node to continue node processing */
838 } else {
839 *pseudo = UNKNOWN_KIND; /* regular node (not cell or generator) */
840 }
841 if (0 == strcmp(tok1, "void")) { /* automatic unambiguous naming for "void" */
842 (void) snprintf(tok3, (size_t) (STRLENGTH-1L), "_void%ld", Num_Voids);
844 width = 0L; /* width is irrelevant here */
845 } else {
846 (void) strcpy(tok3, tok1);
847 }
848 if (ISEMPTY(str)) { /* all nodes have at least one parameter */
849 if (TOGGLE_KIND != kind) {
850 print_error_location("node", mline, mfile);
851 (void) fprintf(STDERR, " parameters of node <%s> are missing\n", tok3);
852 return (char*) NULL;
853 }
854 }
855 t = strstr(str, "&delayed"); /* detect the presence of short form '&delayed' */
856 if ((char*) NULL != t) {
857 Node_List[Num_Nodes].delayed = true;
858 for (i = 0; i < 7; i++) { /* clear processed '&delayed' from instruction */
859 *t++ = ' ';
860 }
861 *t = ' ';
862 } else {
863 Node_List[Num_Nodes].delayed = false;
864 }
865 resolve_pathnames(str, depth); /* resolve pathnames using conventions */
866 if (!Node_List[Num_Nodes].delayed) {
867 strcpy_alloc(&(Node_List[Num_Nodes].name1), tok3, mline, mfile); /* node name */
868 strcpy_alloc(&(Node_List[Num_Nodes].name2), tok3, mline, mfile); /* copy of node name */
869 strcpy_alloc(&(Node_List[Num_Nodes].value), str, mline, mfile); /* unprocessed node_value */
870 } else if (0 == strcmp(tok1, "void")) {
871 strcpy_alloc(&(Node_List[Num_Nodes].name1), tok3, mline, mfile); /* node name */
872 strcpy_alloc(&(Node_List[Num_Nodes].name2), tok3, mline, mfile); /* copy of node name */
873 if ((IUSER_KIND == kind) || (DUSER_KIND == kind) || (ITOOL_KIND == kind) || (DTOOL_KIND == kind)) {
874 (void) snprintf(tok11, (size_t) (LINLENGTH-1L), "%s delayed_node$", str); /* add an option to user or tool */
875 strcpy_alloc(&(Node_List[Num_Nodes].value), tok11, mline, mfile); /* unprocessed node_value */
876 } else {
877 strcpy_alloc(&(Node_List[Num_Nodes].value), str, mline, mfile); /* unprocessed node_value */
878 }
879 } else {
880 (void) snprintf(tok9, (size_t) (LINLENGTH-1L), "%s_intern", tok3);
881 strcpy_alloc(&(Node_List[Num_Nodes].name1), tok9, mline, mfile); /* new node name */
882 strcpy_alloc(&(Node_List[Num_Nodes].name2), tok9, mline, mfile); /* copy of new node name */
883 if ((IUSER_KIND == kind) || (DUSER_KIND == kind) || (ITOOL_KIND == kind) || (DTOOL_KIND == kind)) {
884 (void) snprintf(tok11, (size_t) (LINLENGTH-1L), "%s delayed_node$", str); /* add an option to user or tool */
885 strcpy_alloc(&(Node_List[Num_Nodes].value), tok11, mline, mfile); /* unprocessed node_value */
886 } else {
887 strcpy_alloc(&(Node_List[Num_Nodes].value), str, mline, mfile); /* unprocessed node_value */
888 }
889 }
890 Node_List[Num_Nodes].aliased = false; /* not aliased yet */
891 strcpy_alloc(&(Node_List[Num_Nodes].tag), tok2, mline, mfile); /* node tag (kind name) */
892 strcpy_alloc(&(Node_List[Num_Nodes].option), "", mline, mfile); /* currently empty */
893 Node_List[Num_Nodes].ID = Num_Nodes; /* unique node ID */
894 Node_List[Num_Nodes].kind = kind; /* node kind determination */
895 Node_List[Num_Nodes].width = width; /* width ( -/+ <=> unsigned/signed) */
896 Node_List[Num_Nodes].segment = Num_Segments - 1L; /* record segment level */
897 Node_List[Num_Nodes].determined = false; /* not yet determined */
898 Node_List[Num_Nodes].init = false; /* not yet initialized */
899 Node_List[Num_Nodes].flag = MAYBE; /* not yet allowed to be initialized */
900 Node_List[Num_Nodes].type = UNKNOWN_TYPE; /* type is not yet identified */
901 Node_List[Num_Nodes].declare = UNKNOWN_TYPE; /* no declaration yet */
902 Node_List[Num_Nodes].inject = false; /* no noise injection yet */
903 Node_List[Num_Nodes].used = /* void node are considered as used */
904 ((0 != strncmp(Node_List[Num_Nodes].name1, "_void", (size_t) 5)) && (!flag)) ? false : true;
905 for (d = 0L; d < MAXDEPTH; d++) {
906 Node_List[Num_Nodes].mline[d] = mline[d]; /* record line for identification */
907 Node_List[Num_Nodes].mfile[d] = mfile[d]; /* record file for identification */
908 }
909 Node_List[Num_Nodes].errflag = 0L; /* flag error (neg) */
910 Node_List[Num_Nodes].ID2 = 0L; /* user func id */
911 Segment_List[Num_Segments-1L].used2 = true;
912 for (;;) { /* check for node self-referencing */
913 str = get_sign_and_token(str, sgn, tok8);
914 if (ISEMPTY(tok8)) {
915 break;
916 }
917 if (0 == strcmp(tok8, Node_List[Num_Nodes].name1)) {
918 print_error_location("node", mline, mfile);
919 (void) fprintf(STDERR, " <%s> : self-reference is not allowed in a node definition,\n", Node_List[Num_Nodes].name1);
920 (void) fprintf(STDERR, " unless the node is delayed with '&delayed' short form\n");
921 /* parsing of instruction may continue */
922 }
923 }
924 increment_node_number("node");
925 if ((Node_List[Num_Nodes-1L].delayed) && (0 != strcmp(tok1, "void"))) { /* create a node 'delay' after this node */
926 if (DELAY_KIND == Node_List[Num_Nodes-1L].kind) {
927 print_error_location("node", mline, mfile);
928 (void) fprintf(STDERR, " delay node <%s> cannot be delayed with '&delayed' short form\n", Node_List[Num_Nodes-1].name1);
929 /* parsing of instruction may continue */
930 }
931 strcpy_alloc(&(Node_List[Num_Nodes].name1), tok3, mline, mfile); /* node name */
932 strcpy_alloc(&(Node_List[Num_Nodes].name2), tok3, mline, mfile); /* copy of node name */
933 Node_List[Num_Nodes].aliased = false; /* not aliased yet */
934 strcpy_alloc(&(Node_List[Num_Nodes].tag), tok2, mline, mfile); /* use node tag (kind name) of delayed node */
935 (void) snprintf(tok10, (size_t) (LINLENGTH-1L), "1 %s", tok9); /* value of this created delay node */
936 strcpy_alloc(&(Node_List[Num_Nodes].value), tok10, mline, mfile); /* unprocessed node_value */
937 strcpy_alloc(&(Node_List[Num_Nodes].option), "", mline, mfile); /* no option */
938 Node_List[Num_Nodes].ID = Num_Nodes; /* unique node ID */
939 Node_List[Num_Nodes].kind = DELAY_KIND; /* node kind */
940 Node_List[Num_Nodes].width = width; /* width ( -/+ <=> unsigned/signed) */
941 Node_List[Num_Nodes].segment = Num_Segments - 1L; /* record segment level */
942 Node_List[Num_Nodes].determined = false; /* not yet determined */
943 Node_List[Num_Nodes].delayed = false; /* reset flag */
944 Node_List[Num_Nodes].init = false; /* not yet initialized */
945 Node_List[Num_Nodes].flag = MAYBE; /* not yet allowed to be initialized */
946 Node_List[Num_Nodes].type = UNKNOWN_TYPE; /* type is not yet identified */
947 Node_List[Num_Nodes].declare = UNKNOWN_TYPE; /* no declaration yet */
948 Node_List[Num_Nodes].inject = false; /* no noise injection yet */
949 Node_List[Num_Nodes].used = /* void node are considered as used */
950 ((0 != strncmp(Node_List[Num_Nodes].name1, "_void", (size_t) 5)) && (!flag)) ? false : true;
951 for (d = 0L; d < MAXDEPTH; d++) {
952 Node_List[Num_Nodes].mline[d] = mline[d]; /* record line for identification */
953 Node_List[Num_Nodes].mfile[d] = mfile[d]; /* record file for identification */
954 }
955 Node_List[Num_Nodes].errflag = 0L; /* flag error (neg) */
956 Node_List[Num_Nodes].ID2 = 0L; /* user func id */
957 Segment_List[Num_Segments-1L].used2 = true;
958 Num_Creates++;
959 increment_node_number("node");
960 }
961 return (char*) NULL;
962}
void increment_node_number(const char *kind)
Definition id.c:413
long node_kind(const char *identifier)
Definition id.c:1236
void increment_void_number(void)
Definition id.c:564
char * get_node(char *str, char *nodnam, long *pseudo)
Definition lp.c:600
void process_node_kind_error(const char *kind)
Definition mp.c:132
void process_node_error(const char *tok1)
Definition mp.c:259
#define CONST_KIND
Definition napa.h:246
#define IUSER_KIND
Definition napa.h:280
#define DUSER_KIND
Definition napa.h:261
#define TEST_KIND
Definition napa.h:316
EXTERN long Num_Nodes
Definition napa.h:824
#define TOGGLE_KIND
Definition napa.h:317
#define SET_KIND
Definition napa.h:308
#define DALGEBRA_KIND
Definition napa.h:251
#define DC_KIND
Definition napa.h:252
#define IALGEBRA_KIND
Definition napa.h:274
#define ITOOL_KIND
Definition napa.h:279
#define DTOOL_KIND
Definition napa.h:260
#define MAX(x, y)
Definition napa.h:377
EXTERN long Num_Creates
Definition napa.h:808
#define GEN_KIND
Definition napa.h:272
#define DELAY_KIND
Definition napa.h:253
#define ALGEBRA_KIND
Definition napa.h:227
#define MAYBE
Definition napa.h:405
#define CELL_KIND
Definition napa.h:241
char * expand_nodeset(char *str, long n, long w, const unsigned long *mlin, const unsigned long *mfil)
Definition tk.c:969
void replace_parentheses(char *str)
Definition tk.c:1644
char * get_function_identifier(char *str, char *fun_id, char *fun_parm)
Definition tk.c:1036
long record_function_identifier(const char *tok, long m, const unsigned long *mlin, const unsigned long *mfil)
Definition rd.c:1656

References ALGEBRA_KIND, alias_id(), Alias_List, array_id(), Array_List, CELL_KIND, CONST_KIND, DALGEBRA_KIND, DC_KIND, DELAY_KIND, directive_id(), Directive_List, DTOOL_KIND, DUSER_KIND, ERROR, Expand_Flag, expand_nodeset(), GEN_KIND, get_function_identifier(), get_node(), get_sign_and_token(), get_token_between_braces(), IALGEBRA_KIND, increment_node_number(), increment_void_number(), is_a_keyword(), is_an_identifier(), ISEMPTY, ISNOTEMPTY, ITOOL_KIND, IUSER_KIND, LINLENGTH, MAX, MAXDEPTH, MAYBE, node_id(), node_kind(), Node_List, Num_Creates, Num_Nodes, Num_Segments, Num_Voids, print_error_location(), print_location(), print_warning_location(), process_node_error(), process_node_kind_error(), record_function_identifier(), record_id(), Record_List, replace_parentheses(), resolve_pathnames(), Segment_List, SET_KIND, STDERR, STDOUT, strcpy_alloc(), STRLENGTH, TEST_KIND, TOGGLE_KIND, UNDEFINED, UNKNOWN_KIND, UNKNOWN_TYPE, var_id(), Var_List, and WARNING.

Referenced by get_node(), and line_parsing().

◆ get_nominal()

void get_nominal ( char * str)

Definition at line 1795 of file lp.c.

1795 {
1796
1797 /* INSTRUCTION: NOMINAL */
1798 /* - "fs" mandatory */
1799
1800 char tok1[STRLENGTH] = {'\0'};
1801 char sgn[2] = {'\0'};
1802 long d;
1803
1804 if (data_flag[depth]) {
1805 print_error_location("data", mline, mfile);
1806 (void) fprintf(STDERR, " instruction 'nominal' is not allowed in a data cell file\n");
1808 }
1809 if (0L != width) {
1810 print_warning_location("nominal", mline, mfile);
1811 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width);
1812 }
1813 str = get_sign_and_token(str, sgn, tok1);
1814 if (0 != strcmp(tok1, "fs")) {
1815 print_error_location("nominal", mline, mfile);
1816 (void) fprintf(STDERR, " syntax error, keyword 'fs' is missing\n");
1817 }
1818 Drop_Flag = false; /* reset Drop_Flag as it is an absolute reference */
1819 Segment_List[Num_Segments].rate = 1.0; /* NOMINAL is a simplified DECIMATE instruction */
1820 Segment_List[Num_Segments].offset = 0.0;
1822 Segment_List[Num_Segments].ref = 1L; /* always referred to global sampling frequency */
1823 Segment_List[Num_Segments].used1 = false;
1824 Segment_List[Num_Segments].used2 = false;
1825 Segment_List[Num_Segments].used3 = false;
1826 Segment_List[Num_Segments].periodic = true;
1827 for (d = 0L; d < MAXDEPTH; d++) {
1828 Segment_List[Num_Segments].mline[d] = mline[d];
1829 Segment_List[Num_Segments].mfile[d] = mfile[d];
1830 }
1831 increment_segment_number("nominal");
1832 return;
1833}
#define NOMINAL_SEGMENT_TYPE
Definition napa.h:350

References Drop_Flag, get_sign_and_token(), increment_segment_number(), MAXDEPTH, NOMINAL_SEGMENT_TYPE, Num_Segments, print_error_banner_and_exit(), print_error_location(), print_warning_location(), Segment_List, STDERR, and STRLENGTH.

Referenced by line_parsing().

◆ get_opcode()

void get_opcode ( char * str)

Definition at line 4119 of file lp.c.

4119 {
4120
4121 /* INSTRUCTION: OPCODE */
4122 /* - owner name mandatory */
4123 /* - opcode number integer > 0 */
4124 /* - function mandatory */
4125
4126 char tok1[STRLENGTH] = {'\0'};
4127 char tok2[STRLENGTH] = {'\0'};
4128 char tok3[STRLENGTH] = {'\0'};
4129 char sgn[2] = {'\0'};
4130 long d, i;
4131
4132 str = get_token(str, tok1, false);
4133 if (0L != width) {
4134 print_error_location("opcode", mline, mfile);
4135 (void) fprintf(STDERR, " opcode <%s> cannot be width limited\n", tok1);
4136 /* parsing of instruction may continue */
4137 }
4138 if (!is_an_identifier(tok1)) {
4139 print_error_location("opcode", mline, mfile);
4140 (void) fprintf(STDERR, " opcode name <%s> is not a NAPA identifier\n", tok1);
4141 return;
4142 }
4143 strcpy_alloc(&(Opcode_List[Num_Opcodes].name), tok1, mline, mfile);
4144 str = get_sign_and_token(str, sgn, tok3);
4145 (void) snprintf(tok2, (size_t) (STRLENGTH-1L), "%s%s", sgn, tok3); /* signed integer value */
4146 if (1 != sscanf(tok2, "%li", &i)) {
4147 print_error_location("opcode", mline, mfile);
4148 (void) fprintf(STDERR, " opcode for <%s> is not a well-formed positive C integer <%s>\n", tok1, tok2);
4149 return;
4150 }
4151 if (0 > i) {
4152 print_error_location("opcode", mline, mfile);
4153 (void) fprintf(STDERR, " opcode for <%s> cannot be a negative number\n", tok1);
4154 return;
4155 }
4156 Opcode_List[Num_Opcodes].code = i;
4157 clean_parentheses(str);
4158 strcpy_alloc(&(Opcode_List[Num_Opcodes].function), str, mline, mfile);
4159 for (d = 0L; d < MAXDEPTH; d++) {
4160 Opcode_List[Num_Opcodes].mline[d] = mline[d]; /* record line for identification */
4161 Opcode_List[Num_Opcodes].mfile[d] = mfile[d]; /* record file for identification */
4162 }
4163 increment_opcode_number("opcode");
4164 return;
4165}
void increment_opcode_number(const char *kind)
Definition id.c:427
EXTERN OPCODE_TYPE Opcode_List[127L]
Definition napa.h:963
EXTERN long Num_Opcodes
Definition napa.h:826

References clean_parentheses(), get_sign_and_token(), get_token(), increment_opcode_number(), is_an_identifier(), MAXDEPTH, Num_Opcodes, Opcode_List, print_error_location(), STDERR, strcpy_alloc(), and STRLENGTH.

Referenced by line_parsing().

◆ get_output()

void get_output ( char * str)

Definition at line 2220 of file lp.c.

2220 {
2221
2222 /* INSTRUCTION: OUTPUT */
2223 /* - stream name mandatory */
2224 /* - output list mandatory */
2225
2226 /* Stream and output list are stored for further processing */
2227
2228 char tok1[STRLENGTH] = {'\0'};
2229 char tok2[STRLENGTH] = {'\0'};
2230 long d;
2231 int i;
2232
2233 if (data_flag[depth]) {
2234 print_error_location("data", mline, mfile);
2235 (void) fprintf(STDERR, " instruction 'output' is not allowed in a data cell file\n");
2236 return;
2237 }
2238 if (0L != width) {
2239 print_error_location("output", mline, mfile);
2240 (void) fprintf(STDERR, " output cannot be width limited\n");
2241 /* parsing of instruction may continue */
2242 }
2243 str = get_token(str, tok1, true);
2244 if (ISEMPTY(tok1)) {
2245 print_error_location("output", mline, mfile);
2246 (void) fprintf(STDERR, " output stream is missing\n");
2247 return;
2248 }
2249 if (ISEMPTY(str)) {
2250 print_error_location("output", mline, mfile);
2251 (void) fprintf(STDERR, " output list is missing\n");
2252 return;
2253 }
2254 resolve_pathnames(tok1, depth); /* resolve pathname using conventions */
2255 (void) get_token(tok1, tok2, false);
2256 simplify_pathname(tok2);
2257 for (i = 0; i < Num_IOs; i++) {
2258 if (0 == fnstrcmp(IO_List[i].fname, tok2)) {
2259 print_error_location("output", mline, mfile);
2260 (void) fprintf(STDERR, " collision between I/O streams, <%s> is already defined", tok2);
2261 if (INPUT_TYPE == IO_List[i].type) {
2262 (void) fprintf(STDERR, " as input\n");
2263 }
2264 if (OUTPUT_TYPE == IO_List[i].type) {
2265 (void) fprintf(STDERR, " as output\n");
2266 }
2267 }
2268 }
2269 if (Dump_Flag) {
2270 if (0 == fnstrcmp(Dump_List.fname, tok2)) {
2271 print_error_location("output", mline, mfile);
2272 (void) fprintf(STDERR, " collision with I/O streams, <%s> is already defined as a dump file", tok2);
2273 }
2274 }
2275 strcpy_alloc(&(IO_List[Num_IOs].fname), tok2, mline, mfile); /* out_filename without "" */
2276 strcpy_alloc(&(IO_List[Num_IOs].element), str, mline, mfile); /* unprocessed I/O list of elements */
2277 IO_List[Num_IOs].segment = Num_Segments-1L;
2278 IO_List[Num_IOs].type = OUTPUT_TYPE; /* record io type */
2279 IO_List[Num_IOs].event = false; /* not yet determined */
2280 Segment_List[Num_Segments-1L].used3 = true;
2281 for (d = 0L; d < MAXDEPTH; d++) {
2282 IO_List[Num_IOs].mline[d] = mline[d]; /* record line for identification */
2283 IO_List[Num_IOs].mfile[d] = mfile[d]; /* record file for identification */
2284 }
2285 Output_Flag = true;
2286 increment_IO_number("output");
2287 return;
2288}
EXTERN int Output_Flag
Definition napa.h:872

References Dump_Flag, Dump_List, fnstrcmp(), get_token(), increment_IO_number(), INPUT_TYPE, IO_List, ISEMPTY, MAXDEPTH, Num_IOs, Num_Segments, Output_Flag, OUTPUT_TYPE, print_error_location(), resolve_pathnames(), Segment_List, simplify_pathname(), STDERR, strcpy_alloc(), and STRLENGTH.

Referenced by line_parsing().

◆ get_ping()

void get_ping ( char * str)

Definition at line 3197 of file lp.c.

3197 {
3198
3199 /* INSTRUCTION: PING */
3200 /* - ping keywords */
3201
3202 char tok1[STRLENGTH] = {'\0'};
3203 long d;
3204 long v;
3205
3206 if (Ping_Flag) {
3207 print_warning_location("ping", mline, mfile);
3208 (void) fprintf(STDERR, " there are multiple ping instructions in this netlist\n");
3209 return;
3210 }
3211 Ping_Flag = true;
3212 if (0L < depth) {
3213 print_error_location("ping", mline, mfile);
3214 (void) fprintf(STDERR, " this special instruction is allowed only in the main netlist file\n");
3215 return;
3216 }
3217 if (0L != width) {
3218 print_warning_location("ping", mline, mfile);
3219 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width);
3220 }
3221 str = get_token(str, tok1, false);
3222 if (ISEMPTY(tok1)) { /* default is "stderr" */
3223 (void) strcpy(tok1, "stderr");
3224 }
3225 v = var_id(tok1);
3226 if (UNDEFINED != v) {
3227 if (STRING_DATA_TYPE != Var_List[v].type) {
3228 print_error_location("ping", mline, mfile);
3229 (void) fprintf(STDERR, " ping file name is not a string\n");
3230 }
3231 str = Var_List[v].value;
3232 str = get_token(str, tok1, false);
3233 }
3234 if (0 == strcmp(tok1, "stdin")) {
3235 print_error_location("ping", mline, mfile);
3236 (void) fprintf(STDERR, " ping output stream cannot be \"stdin\"\n");
3237 return;
3238 }
3239 if (0 == strcmp(tok1, "stdout")) {
3240 print_error_location("ping", mline, mfile);
3241 (void) fprintf(STDERR, " to avoid collision, ping output stream cannot be \"stdout\"\n");
3242 return;
3243 }
3244 resolve_pathnames(tok1, depth); /* resolve pathname using conventions */
3245 strcpy_alloc(&(Ping_List.fname), tok1, mline, mfile); /* filename without "" */
3246 for (d = 0L; d < MAXDEPTH; d++) {
3247 Ping_List.mline[d] = mline[d]; /* record line for identification */
3248 Ping_List.mfile[d] = mfile[d]; /* record file for identification */
3249 }
3250 return;
3251}
EXTERN PING_TYPE Ping_List
Definition napa.h:977
EXTERN int Ping_Flag
Definition napa.h:874

References get_token(), ISEMPTY, MAXDEPTH, Ping_Flag, Ping_List, print_error_location(), print_warning_location(), resolve_pathnames(), STDERR, strcpy_alloc(), STRING_DATA_TYPE, STRLENGTH, UNDEFINED, var_id(), and Var_List.

Referenced by line_parsing().

◆ get_post()

void get_post ( char * str)

Definition at line 1319 of file lp.c.

1319 {
1320
1321 /* INSTRUCTION: POST (of a tool, of an output) */
1322 /* - label id optional */
1323 /* - tool id mandatory */
1324 /* - parameters optional */
1325
1326 static long counter = -2;
1327 char tok1[STRLENGTH] = {'\0'};
1328 char tok2[STRLENGTH] = {'\0'};
1329 char tok3[STRLENGTH] = {'\0'};
1330 char tok4[STRLENGTH] = {'\0'};
1331 char tok5[STRLENGTH] = {'\0'};
1332 char ifil[STRLENGTH] = {'\0'};
1333 char ofil[STRLENGTH] = {'\0'};
1334 char sgn[2] = {'\0'};
1335 char *s = (char*) NULL;
1336 long d, i;
1337 long label, existing;
1338 long num;
1339 static long start = 0L;
1340 static long prev_num_groups = -1L;
1341 int flag;
1342
1343
1344 /* 'Num_Groups' is reset at each instantiation of a node or an output, */
1345 /* see functions 'increment_node()' and 'increment_IO()' */
1346
1347 if ((0L == Num_Groups) && (prev_num_groups != Num_Groups)) {
1348 start = Num_Posts;
1349 }
1350
1351 if (data_flag[depth]) {
1352 print_error_location("data", mline, mfile);
1353 (void) fprintf(STDERR, " instruction 'post' is not allowed in a data cell file\n");
1354 return;
1355 }
1356 if (0L != width) {
1357 print_warning_location("post", mline, mfile);
1358 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width);
1359 }
1360 str = get_sign_and_token(str, sgn, tok1);
1361 (void) snprintf(tok2, (size_t) (STRLENGTH-1L), "%s%s", sgn, tok1); /* signed long val */
1362 if (1 != sscanf(tok2, "%li", &label)) {
1363 label = counter; /* no label -> generating unique number */
1364 counter--;
1365 } else {
1366 if (0L >= label) {
1367 print_error_location("post", mline, mfile);
1368 (void) fprintf(STDERR, " label is not a strictly positive integer <%s>\n", tok2);
1370 }
1371 str = get_sign_and_token(str, sgn, tok1);
1372 }
1373 if (ISNOTEMPTY(sgn)) {
1374 print_error_location("post", mline, mfile);
1375 (void) fprintf(STDERR, " no sign expected in front of the function identifier <%s>\n", tok1);
1376 return;
1377 }
1378 if (ISEMPTY(tok1)) {
1379 print_error_location("post", mline, mfile);
1380 (void) fprintf(STDERR, " function identifier is missing\n");
1381 return;
1382 }
1383 (void) snprintf(tok2, (size_t) (STRLENGTH-1L), "post_%s", tok1);
1384 resolve_pathnames(str, depth); /* resolve pathnames using conventions */
1385 replace_parentheses(str); /* replace (..) by ..$ in qualifiers */
1386 strcpy_alloc(&(Post_List[Num_Posts].function), tok2, mline, mfile); /* function id */
1387 (void) strcpy(tok3, "");
1388 (void) strcpy(tok4, "");
1389 for (;;) {
1390 str = get_token(str, tok5, true);
1391 if (ISEMPTY(tok5)) {
1392 break;
1393 }
1394 if ('$' == tok5[(LENGTH(tok5)) - 1L]) { /* this is an option */
1395 tok5[(LENGTH(tok5)) - 1L] = '\0'; /* remove the '$' */
1396 (void) strcat(tok3, tok5);
1397 (void) strcat(tok3, " ");
1398 } else {
1399 (void) strcat(tok4, tok5);
1400 (void) strcat(tok4, " ");
1401 }
1402 }
1403 strcpy_alloc(&(Post_List[Num_Posts].option), tok3, mline, mfile);
1404 strcpy_alloc(&(Post_List[Num_Posts].parms), tok4, mline, mfile);
1405 num = 0L;
1406 for (i = 0L; i < Num_Posts; i++) {
1407 if (0 == strcmp(tok2, Post_List[i].function)) {
1408 num++;
1409 }
1410 }
1411 Post_List[Num_Posts].ID = num; /* unique ID per instantiation of function */
1412 num = 0L;
1413 s = Post_List[Num_Posts].parms;
1414 s = get_sign_and_token(s, sgn, tok1);
1415 for (;;) {
1416 if (ISEMPTY(tok1)) {
1417 break;
1418 }
1419 s = get_sign_and_token(s, sgn, tok1);
1420 num++;
1421 }
1422 Post_List[Num_Posts].number = num; /* number of parameters */
1423 if (0 == strcmp(Last_Instruction, "post")) {
1424 (void) strcpy(Last_Instruction, Last_Postprocess);
1425 }
1426 existing = -1L; /* new label */
1427 for (i = 0L; i < Num_Groups; i++) {
1428 if (Group_List[i].ID == label) {
1429 existing = i;
1430 break;
1431 }
1432 }
1433
1434 if (-1L == existing) {
1435 /* new group of postprocess, look at the output file of tool or time domain output */
1436 if (((0L < Num_Nodes) && (0 == strcmp(Last_Instruction, "node"))) || (0 == strcmp(Last_Instruction, "tool"))) {
1437 if ((ITOOL_KIND != Node_List[Num_Nodes-1L].kind) && (DTOOL_KIND != Node_List[Num_Nodes-1L].kind)) {
1438 print_error_location("post", mline, mfile);
1439 (void) fprintf(STDERR, " this instruction must immediately follow another postprocess, a tool or an output\n");
1440 return;
1441 }
1442 s = Node_List[Num_Nodes-1L].value;
1443 s = get_token(s, tok1, true);
1444 strcpy_alloc(&(Post_List[Num_Posts].origin), tok1, mline, mfile); /* store node kind */
1445 flag = false;
1446 for (;;) {
1447 s = get_token(s, tok1, true);
1448 if (ISEMPTY(tok1)) {
1449 break;
1450 }
1451 if (STRING_DATA_TYPE == get_type(tok1)) {
1452 flag = true;
1453 break;
1454 }
1455 }
1456 if (!flag) {
1457 (void) strcpy(ifil, "");
1458 }
1459 (void) strcpy(ifil, tok1);
1460 if (ISEMPTY(ifil)) {
1461 print_error_location("post", mline, mfile);
1462 (void) fprintf(STDERR, " there is no file from tool node to postprocess\n");
1463 return;
1464 }
1465 (void) strcpy(Last_Postprocess, "node");
1466 } else if ((0L < Num_IOs) && (0 == strcmp(Last_Instruction, "output"))) {
1467 strcpy_alloc(&(Post_List[Num_Posts].origin),"output", mline, mfile); /* store IO kind */
1468 if (UNDEFINED == var_id(IO_List[Num_IOs-1L].fname)) {
1469 (void) snprintf(ifil, (size_t) (STRLENGTH-1L), "\"%s\"", (IO_List[Num_IOs-1L]).fname);
1470 } else {
1471 (void) strcpy(ifil, (IO_List[Num_IOs-1L]).fname);
1472 }
1473 (void) strcpy(Last_Postprocess, "output");
1474 } else if (0 == strcmp(Last_Instruction, "void")) {
1475 strcpy_alloc(&(Post_List[Num_Posts].origin), "void", mline, mfile); /* store IO kind */
1477 (void) snprintf(ifil, (size_t) (STRLENGTH-1L), "\"%s\"", Void_List_Name);
1478 } else {
1479 (void) strcpy(ifil, Void_List_Name);
1480 }
1481 (void) strcpy(Last_Postprocess, "void");
1482 } else {
1483 print_error_location("post", mline, mfile);
1484 (void) fprintf(STDERR, " this instruction must follow immediately another postprocess, a tool or an output\n");
1485 (void) strcpy(Last_Postprocess, "");
1486 return;
1487 }
1488 Group_List[Num_Groups].ID = label;
1489 strcpy_alloc(&(Group_List[Num_Groups].ifname), ifil, mline, mfile);
1490 strcpy_alloc(&(Group_List[Num_Groups].ofname), "", mline, mfile);
1491 prev_num_groups = Num_Groups;
1492
1493 } else {
1494 /* existing group of postprocess, outfile becomes now input file */
1495 (void) strcpy(ifil, Group_List[existing].ofname);
1496 if (ISEMPTY(ifil)) {
1497 print_error_location("post", mline, mfile);
1498 (void) fprintf(STDERR, " there is no file to postprocess\n");
1499 return;
1500 }
1501 strcpy_realloc(&(Group_List[existing].ifname), ifil, mline, mfile);
1502 strcpy_realloc(&(Group_List[existing].ofname), "", mline, mfile);
1503 strcpy_alloc(&(Post_List[Num_Posts].origin), Post_List[Num_Posts-1].origin, mline, mfile);
1504 }
1505
1506 if ((0 == strcmp(ifil, "\"stdout\""))|| (0 == strcmp(ifil, "\"stderr\"")) || (0 == strcmp(ifil, "\"stdin\"" ))) {
1507 print_error_location("post", mline, mfile);
1508 (void) fprintf(STDERR, " standard IO stream <%s> cannot be postprocessed\n", ifil);
1509 return;
1510 }
1511
1512 flag = false;
1513 s = Post_List[Num_Posts].parms;
1514 for (;;) { /* look after possible output file */
1515 s = get_token(s, tok1, true);
1516 if (ISEMPTY(tok1)) {
1517 break;
1518 }
1519 if (STRING_DATA_TYPE == get_type(tok1)) {
1520 flag = true;
1521 break;
1522 }
1523 }
1524 if (!flag) {
1525 (void) strcpy(ofil, "");
1526 } else if (UNDEFINED != var_id(tok1)) {
1527 (void) strcpy(ofil, Var_List[var_id(tok1)].value);
1528 } else {
1529 (void) strcpy(ofil, tok1);
1530 }
1531 strcpy_alloc(&(Post_List[Num_Posts].ofname), ofil, mline, mfile);
1532
1533 if (0 == strcmp(Post_List[Num_Posts].function, "post_void")) {
1534 if (0 > label) {
1535 print_error_location("post", mline, mfile);
1536 (void) fprintf(STDERR, " a void post instruction must have a label\n");
1537 return;
1538 }
1539 flag = false;
1540 for (i = start; i < Num_Posts; i++) {
1541 if (0 == fnstrcmp(Post_List[i].ofname, ofil)) {
1542 flag = true;
1543 break;
1544 }
1545 }
1546 if (0 == fnstrcmp(ifil, ofil)) {
1547 flag = true;
1548 }
1549 if (!flag) {
1550 print_error_location("post", mline, mfile);
1551 (void) fprintf(STDERR, " file <%s> cannot be postprocessed\n", ofil);
1552 return;
1553 }
1554 }
1555
1556 if (-1L == existing) {
1557 strcpy_realloc(&(Group_List[Num_Groups].ofname), ofil, mline, mfile);
1558 } else {
1559 strcpy_realloc(&(Group_List[existing].ofname), ofil, mline, mfile);
1560 }
1561 (void) snprintf(tok1, (size_t) (STRLENGTH-1L), "%s %s", ifil, Post_List[Num_Posts].parms); /* file name */
1562 strcpy_realloc(&(Post_List[Num_Posts].parms), tok1, mline, mfile);
1563 for (d = 0L; d < MAXDEPTH; d++) {
1564 Post_List[Num_Posts].mline[d] = mline[d]; /* record line for identification */
1565 Post_List[Num_Posts].mfile[d] = mfile[d]; /* record file for identification */
1566 }
1567 Post_List[Num_Posts].segment = Num_Segments - 1L;
1568 Post_Flag = true;
1569 increment_post_number("post");
1570 if (-1L == existing) {
1571 increment_group_number("post");
1572 }
1573 return;
1574}
long get_type(char *identifier)
Definition id.c:1190
void increment_post_number(const char *kind)
Definition id.c:440
void increment_group_number(const char *kind)
Definition id.c:334
EXTERN long Num_Groups
Definition napa.h:817
EXTERN int Post_Flag
Definition napa.h:876
EXTERN char Last_Postprocess[2047L]
Definition napa.h:893
EXTERN POST_TYPE Post_List[63L]
Definition napa.h:964
EXTERN long Num_Posts
Definition napa.h:827
EXTERN char Void_List_Name[2047L]
Definition napa.h:917
EXTERN GROUP_TYPE Group_List[31L]
Definition napa.h:958
EXTERN char Last_Instruction[2047L]
Definition napa.h:892

References DTOOL_KIND, fnstrcmp(), get_sign_and_token(), get_token(), get_type(), Group_List, increment_group_number(), increment_post_number(), IO_List, ISEMPTY, ISNOTEMPTY, ITOOL_KIND, Last_Instruction, Last_Postprocess, LENGTH, MAXDEPTH, Node_List, Num_Groups, Num_IOs, Num_Nodes, Num_Posts, Num_Segments, Post_Flag, Post_List, print_error_banner_and_exit(), print_error_location(), print_warning_location(), replace_parentheses(), resolve_pathnames(), STDERR, strcpy_alloc(), strcpy_realloc(), STRING_DATA_TYPE, STRLENGTH, UNDEFINED, var_id(), Var_List, and Void_List_Name.

Referenced by line_parsing().

◆ get_random_seed()

void get_random_seed ( const char * str)

Definition at line 3584 of file lp.c.

3584 {
3585
3586 /* INSTRUCTION: RANDOM_SEED */
3587 /* - random_seed value mandatory, long integer */
3588 /* random_seed instruction should be unique */
3589
3590 long d;
3591
3592 if (0L != width) {
3593 print_warning_location("random_seed", mline, mfile);
3594 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width);
3595 }
3596 if (ISEMPTY(str)) {
3597 print_error_location("random_seed", mline, mfile);
3598 (void) fprintf(STDERR, " seed of the random number is missing\n");
3599 return;
3600 }
3601 if (Seed_Flag) {
3602 print_warning_location("random_seed", mline, mfile);
3603 (void) fprintf(STDERR, " overwriting a previous definition of random_seed\n");
3604 }
3605 Seed_Flag = true;
3606 if (1 != sscanf(str, "%li", &Seed_List.rndseed)) {
3607 print_error_location("random_seed", mline, mfile);
3608 (void) fprintf(STDERR, " random_seed is not a well-formed C long integer <%s>\n", str);
3609 return;
3610 }
3611 if (0L > Seed_List.rndseed) {
3612 Antithetic_Flag = true;
3613 }
3614 for (d = 0L; d < MAXDEPTH; d++) {
3615 Seed_List.mline[d] = mline[d]; /* record line for identification */
3616 Seed_List.mfile[d] = mfile[d]; /* record file for identification */
3617 }
3618 return;
3619}
EXTERN RANDOMSEED_TYPE Seed_List
Definition napa.h:979
EXTERN int Seed_Flag
Definition napa.h:877
EXTERN int Antithetic_Flag
Definition napa.h:842

References Antithetic_Flag, ISEMPTY, MAXDEPTH, print_error_location(), print_warning_location(), Seed_Flag, Seed_List, and STDERR.

Referenced by line_parsing().

◆ get_restart()

void get_restart ( const char * str)

Definition at line 3086 of file lp.c.

3086 {
3087
3088 /* INSTRUCTION: RESTART */
3089
3090 char buf[STRLENGTH] = {'\0'};
3091 long d;
3092
3093 Update_Flag = true;
3094 if (data_flag[depth]) {
3095 print_error_location("data", mline, mfile);
3096 (void) fprintf(STDERR, " instruction 'restart' is not allowed in a data cell file\n");
3097 return;
3098 }
3099 if (ISNOTEMPTY(str)) {
3100 print_error_location("restart", mline, mfile);
3101 (void) fprintf(STDERR, " instruction 'restart' does not accept any parameter\n");
3102 }
3103 if (0L != width) {
3104 print_warning_location("restart", mline, mfile);
3105 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width);
3106 }
3107 (void) snprintf(buf, (size_t) 31, "$restart$_%ld", Num_Restarts);
3108 increment_restart_number("restart");
3109 strcpy_alloc(&(Update_List[Num_Updates].name), buf, mline, mfile); /* keyword $restart$_.. */
3110 strcpy_alloc(&(Update_List[Num_Updates].value)," ", mline, mfile); /* nothing */
3111 Update_List[Num_Updates].ID = Num_Updates; /* unique update variable ID */
3112 Update_List[Num_Updates].determined = false; /* not yet determined */
3113 Update_List[Num_Updates].event = false; /* not an event variable */
3114 Update_List[Num_Updates].constant = false; /* by default */
3115 Update_List[Num_Updates].segment = Num_Segments - 1L; /* record segment level */
3116 Segment_List[Num_Segments-1L].used1 = true;
3117 for (d = 0L; d < MAXDEPTH; d++) {
3118 Update_List[Num_Updates].mline[d] = mline[d]; /* record line for identification */
3119 Update_List[Num_Updates].mfile[d] = mfile[d]; /* record file for identification */
3120 }
3121 increment_update_number("restart");
3122 return;
3123}
void increment_restart_number(const char *kind)
Definition id.c:466
EXTERN long Num_Restarts
Definition napa.h:830

References increment_restart_number(), increment_update_number(), ISNOTEMPTY, MAXDEPTH, Num_Restarts, Num_Segments, Num_Updates, print_error_location(), print_warning_location(), Segment_List, STDERR, strcpy_alloc(), STRLENGTH, Update_Flag, and Update_List.

Referenced by line_parsing().

◆ get_sampling()

void get_sampling ( char * str)

Definition at line 3402 of file lp.c.

3402 {
3403
3404 /* INSTRUCTION: SAMPLING */
3405 /* - sampling expression mandatory */
3406 /* Sampling instruction must be unique in a simulation */
3407
3408 /* Sampling expression is stored for further processing */
3409
3410 /* Undocumented feature, reserved for experimental study */
3411
3412 long d;
3413
3414 if (data_flag[depth]) {
3415 print_error_location("data", mline, mfile);
3416 (void) fprintf(STDERR, " instruction 'sampling' is not allowed in a data cell file\n");
3417 return;
3418 }
3419 if (0L != width) {
3420 print_warning_location("sampling", mline, mfile);
3421 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width);
3422 }
3423 if ((Fs_Flag) || (Ts_Flag)) {
3424 print_error_location("sampling", mline, mfile);
3425 (void) fprintf(STDERR, " collision with a previous definition of the sampling frequency\n");
3427 return;
3428 }
3429 if (!Periodic_Flag) {
3430 print_error_location("sampling", mline, mfile);
3431 (void) fprintf(STDERR, " only one sampling instruction is allowed in a simulation\n");
3432 return;
3433 }
3434 if (ISEMPTY(str)) {
3435 print_error_location("sampling", mline, mfile);
3436 (void) fprintf(STDERR, " sampling formula is missing\n");
3437 return;
3438 }
3439 clean_parentheses(str);
3440 resolve_pathnames(str, depth); /* resolve pathname using conventions */
3441 strcpy_alloc(&(Sampling_List.formula), str, mline, mfile); /* unprocessed formula */
3442 Sampling_List.segment = Num_Segments - 1L; /* record segment level */
3443 for (d = 0L; d < MAXDEPTH; d++) {
3444 Sampling_List.mline[d] = mline[d]; /* record line for identification */
3445 Sampling_List.mfile[d] = mfile[d]; /* record line for identification */
3446 }
3447 Periodic_Flag = false; /* no guarantee on periodic sampling */
3448 return;
3449}

References clean_parentheses(), Fs_Flag, ISEMPTY, MAXDEPTH, Num_Segments, Periodic_Flag, print_error_location(), print_location(), print_warning_location(), resolve_pathnames(), Sampling_List, STDERR, strcpy_alloc(), and Ts_Flag.

Referenced by line_parsing().

◆ get_stuck()

void get_stuck ( char * str)

Definition at line 2907 of file lp.c.

2907 {
2908
2909 /* INSTRUCTION: STUCK */
2910 /* - node name unsigned, mandatory, defined */
2911 /* - C expression mandatory, no self-reference */
2912
2913 /* Expression is stored for further processing */
2914
2915 char *str2 = (char*) NULL;
2916 char tok1[STRLENGTH] = {'\0'};
2917 char tok2[STRLENGTH] = {'\0'};
2918 char sgn[2] = {'\0'};
2919 long d;
2920
2921 if (0L < depth) {
2922 print_error_location("stuck", mline, mfile);
2923 (void) fprintf(STDERR, " this special instruction is allowed only in the main netlist file\n");
2924 return;
2925 }
2926 str = get_sign_and_token(str, sgn, tok1); /* node_name */
2927 if (0L != width) {
2928 print_error_location("stuck", mline, mfile);
2929 (void) fprintf(STDERR, " redeclaration of width limitation is not allowed\n");
2930 /* parsing of instruction may continue */
2931 }
2932 if (!is_an_identifier(tok1)) {
2933 print_error_location("stuck", mline, mfile);
2934 (void) fprintf(STDERR, " node name <%s> is not a NAPA identifier\n", tok1);
2935 return;
2936 }
2937 if (ISEMPTY(tok1)) {
2938 print_error_location("stuck", mline, mfile);
2939 (void) fprintf(STDERR, " node name is missing\n");
2940 return;
2941 }
2942 if (ISNOTEMPTY(sgn)) {
2943 print_error_location("stuck", mline, mfile);
2944 (void) fprintf(STDERR, " no sign expected in front of the node identifier <%s>\n", tok1);
2945 /* parsing of instruction may continue */
2946 }
2947 if (ISEMPTY(str)) {
2948 print_error_location("stuck", mline, mfile);
2949 (void) fprintf(STDERR, " stuck value is missing\n");
2950 return;
2951 }
2952 str2 = str;
2953 for (;;) { /* check for node self-referencing */
2954 str2 = get_sign_and_token(str2, sgn, tok2);
2955 if (ISEMPTY(tok2)) {
2956 break;
2957 }
2958 if (0 == strcmp(tok2, tok1)) {
2959 print_error_location("stuck", mline, mfile);
2960 (void) fprintf(STDERR, " node <%s> self-reference is not allowed in definition\n", tok1);
2961 /* parsing of instruction may continue */
2962 }
2963 }
2964 strcpy_alloc(&(Stuck_List[Num_Stucks].name), tok1, mline, mfile); /* to be stuck node */
2965 clean_parentheses(str);
2966 resolve_pathnames(str, depth); /* resolve pathname using conventions */
2967 strcpy_alloc(&(Stuck_List[Num_Stucks].value), str, mline, mfile); /* unprocessed value ! */
2968 for (d = 0L; d < MAXDEPTH; d++) {
2969 Stuck_List[Num_Stucks].mline[d] = mline[d]; /* record line for identification */
2970 Stuck_List[Num_Stucks].mfile[d] = mfile[d]; /* record file for identification */
2971 }
2972 increment_stuck_number("stuck");
2973 Stuck_Flag = true;
2974 return;
2975}
void increment_stuck_number(const char *kind)
Definition id.c:492
EXTERN int Stuck_Flag
Definition napa.h:878
EXTERN long Num_Stucks
Definition napa.h:832
EXTERN STUCK_TYPE Stuck_List[63L]
Definition napa.h:967

References clean_parentheses(), get_sign_and_token(), increment_stuck_number(), is_an_identifier(), ISEMPTY, ISNOTEMPTY, MAXDEPTH, Num_Stucks, print_error_location(), resolve_pathnames(), STDERR, strcpy_alloc(), STRLENGTH, Stuck_Flag, and Stuck_List.

Referenced by line_parsing().

◆ get_synchronize()

void get_synchronize ( char * str)

Definition at line 2599 of file lp.c.

2599 {
2600
2601 /* INSTRUCTION: SYNCHRO */
2602 /* - synchro definition optional, checked here */
2603
2604 /* Parameters are stored for further processing */
2605
2606 char tok1[STRLENGTH] = {'\0'};
2607 char brck[3] = {'\0'};
2608
2609 if (data_flag[depth]) {
2610 print_error_location("data", mline, mfile);
2611 (void) fprintf(STDERR, " instruction 'synchronize' is not allowed in a data cell file\n");
2612 return;
2613 }
2614 if (0L != width) {
2615 print_warning_location("synchronize", mline, mfile);
2616 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width);
2617 }
2618 if (ISEMPTY(str)) { /* default option */
2619 Synchro_Flag = true;
2620 return;
2621 }
2622 (void) get_token_between_braces(str, brck, tok1); /* option */
2623 if (0 == strcmp(tok1, "no")) {
2624 Synchro_Flag = false;
2625 } else if ((0 != strcmp(tok1, "yes") && ISNOTEMPTY(tok1)) || (0 != strcmp(brck, "()"))) {
2626 print_error_location("synchronize", mline, mfile);
2627 (void) fprintf(STDERR, " syntax accepts only (yes) or (no)\n");
2628 return;
2629 }
2630 return;
2631}
EXTERN int Synchro_Flag
Definition napa.h:879

References get_token_between_braces(), ISEMPTY, ISNOTEMPTY, print_error_location(), print_warning_location(), STDERR, STRLENGTH, and Synchro_Flag.

Referenced by line_parsing().

◆ get_terminate()

void get_terminate ( char * str)

Definition at line 2559 of file lp.c.

2559 {
2560
2561 /* INSTRUCTION: TERMINATE */
2562 /* - termination condition optional */
2563
2564 long d;
2565
2566 if (data_flag[depth]) {
2567 print_error_location("data", mline, mfile);
2568 (void) fprintf(STDERR, " instruction 'terminate' is not allowed in a data cell file\n");
2569 return;
2570 }
2571 if (0L != width) {
2572 print_warning_location("terminate", mline, mfile);
2573 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width);
2574 }
2575 if (Terminate_Flag) {
2576 print_error_location("terminate", mline, mfile);
2577 (void) fprintf(STDERR, " only one instruction 'terminate' is allowed in a netlist\n");
2578 return;
2579 }
2580 Terminate_Flag = true;
2581 clean_parentheses(str);
2582 resolve_pathnames(str, depth); /* resolve pathname using conventions */
2583 if (ISEMPTY(str)) {
2584 (void) strcpy(str, "true"); /* by default, no loop to process!! */
2585 }
2586 if (0 == strcmp(str, "true")) {
2587 Loop_Flag = false; /* do not build the main loop code */
2588 }
2589 C_syntax_checker(str, mline, mfile);
2590 strcpy_alloc(&(Terminate_List.condition), str, mline, mfile); /* condition */
2591 for (d = 0L; d < MAXDEPTH; d++) {
2592 Terminate_List.mline[d] = mline[d]; /* record line for identification */
2593 Terminate_List.mfile[d] = mfile[d]; /* record file for identification */
2594 }
2595 return;
2596}
EXTERN int Terminate_Flag
Definition napa.h:880
EXTERN TERMINATE_TYPE Terminate_List
Definition napa.h:980
EXTERN int Loop_Flag
Definition napa.h:866

References C_syntax_checker(), clean_parentheses(), ISEMPTY, Loop_Flag, MAXDEPTH, print_error_location(), print_warning_location(), resolve_pathnames(), STDERR, strcpy_alloc(), Terminate_Flag, and Terminate_List.

Referenced by line_parsing().

◆ get_title()

void get_title ( char * str)

Definition at line 3622 of file lp.c.

3622 {
3623
3624 /* INSTRUCTION: TITLE */
3625 /* - title value should be enclosed between quotes */
3626
3627 /* Title is stored for further processing */
3628
3629 char tok1[LINLENGTH] = {'\0'};
3630#if (IS_WIN64 == PLATFORM) /* for WINDOWS/DOS compatibility */
3631 int n;
3632 for (n = 0L; n < LENGTH(str); n++) {
3633 if ('\\' == str[n]) {
3634 str[n] = '/';
3635 }
3636 }
3637#endif
3638 if (0L != width) {
3639 print_warning_location("title", mline, mfile);
3640 (void) fprintf(STDERR, " bit width declaration <%ld> has no meaning here\n", width);
3641 }
3642 str = get_token(str, tok1, false); /* remove quotes */
3643 resolve_pathnames(str, depth); /* resolve pathname using conventions */
3644 if (ISNOTEMPTY(str)) {
3645 print_warning_location("title", mline, mfile);
3646 (void) fprintf(STDERR, " title will be truncated, use double quotes\n");
3647 } else {
3648 if ((LENGTH(Title_String) + LENGTH(tok1)) < LINLENGTH) {
3649 (void) strcat(Title_String, tok1); /* concatenate with previous title */
3650 } else {
3651 print_warning_location("title", mline, mfile);
3652 (void) fprintf(STDERR, " title is too long and will be truncated\n");
3653 }
3654 }
3655 if (ISNOTEMPTY(Title_String)) {
3656 Title_Flag = true;
3657 }
3658 return;
3659}
EXTERN int Title_Flag
Definition napa.h:881
EXTERN char Title_String[2 *2047L]
Definition napa.h:927

References get_token(), ISNOTEMPTY, LENGTH, LINLENGTH, print_warning_location(), resolve_pathnames(), STDERR, Title_Flag, and Title_String.

Referenced by line_parsing().

◆ get_update()

void get_update ( char * str,
const char * instruction )

Definition at line 2126 of file lp.c.

2126 {
2127
2128 /* INSTRUCTION: UPDATE */
2129 /* - variable name unsigned, mandatory, defined */
2130 /* - C expression optional, no check */
2131
2132 /* Expression is stored in tables for further processing */
2133
2134 /* (Note: here self-reference is perfectly right) */
2135 char tok1[STRLENGTH] = {'\0'};
2136 char tok2[STRLENGTH] = {'\0'};
2137 char tok3[STRLENGTH] = {'\0'};
2138 char brc[3] = {'\0'};
2139 char sgn[2] = {'\0'};
2140 char *s = (char*) NULL;
2141 long d;
2142 long ev;
2143 Update_Flag = true;
2144 str = get_sign_and_token(str, sgn, tok1); /* var_name */
2145 if (0L != width) {
2146 if (NOT_INSTRUCTION("event") && NOT_INSTRUCTION("new")) { /* no duplicate error message */
2147 print_error_location(instruction, mline, mfile);
2148 (void) fprintf(STDERR, " redeclaration of width limitation is not allowed when updating a variable\n");
2149 /* parsing of instruction may continue */
2150 }
2151 }
2152 if (!is_an_identifier(tok1)) {
2153 print_error_location(instruction, mline, mfile);
2154 (void) fprintf(STDERR, " variable name <%s> is not a NAPA identifier\n", tok1);
2155 return;
2156 }
2157 if (ISEMPTY(tok1)) {
2158 print_error_location(instruction, mline, mfile);
2159 (void) fprintf(STDERR, " variable name is missing\n");
2160 return;
2161 }
2162 if ((char*) NULL != strchr(tok1, ':')) {
2163 print_error_location(instruction, mline, mfile);
2164 (void) fprintf(STDERR, " %s <%s> cannot include a bit field\n", instruction, tok1);
2165 return;
2166 }
2167 if (ISNOTEMPTY(sgn)) {
2168 print_error_location(instruction, mline, mfile);
2169 (void) fprintf(STDERR, " no sign expected in front of the variable identifier <%s>\n", tok1);
2170 /* parsing of instruction may continue */
2171 }
2172 if (UNDEFINED != node_id(tok1)) {
2173 print_error_location(instruction, mline, mfile);
2174 (void) fprintf(STDERR, " a node cannot be updated <%s>\n", tok1);
2175 return;
2176 }
2177 if (INSTRUCTION("event")) {
2178 clean_parentheses(str);
2179 resolve_pathnames(str, depth); /* resolve pathname using conventions */
2180 s = get_token_between_braces(str, brc, tok2);
2181 if ((0 == strcmp(brc, "()")) && (0 == strcmp(tok2, "new"))) {
2182 (void) strcpy(tok3, "(I_TYPE) ("); /* cast the boolean result to I_TYPE */
2183 (void) strcat(tok3, s);
2184 (void) strcat(tok3, ")");
2185 (void) strcpy(str, tok3);
2186 ev = 2; /* event with '(new)' modifier */
2187 } else {
2188 (void) strcpy(tok3, "(I_TYPE) ("); /* cast the boolean result to I_TYPE */
2189 (void) strcat(tok3, str);
2190 (void) strcat(tok3, ")");
2191 (void) strcpy(str, tok3);
2192 ev = 1; /* this is a regular event */
2193 }
2194 } else { /* not an event */
2195 clean_parentheses(str);
2196 resolve_pathnames(str, depth); /* resolve pathname using conventions */
2197 ev = 0L;
2198 }
2199 strcpy_alloc(&(Update_List[Num_Updates].name), tok1, mline, mfile); /* to be updated var */
2200 strcpy_alloc(&(Update_List[Num_Updates].value), str, mline, mfile); /* unprocessed value */
2201 Update_List[Num_Updates].ID = Num_Updates; /* unique update variable ID */
2202 Update_List[Num_Updates].determined = false; /* not yet determined */
2203 Update_List[Num_Updates].segment = Num_Segments - 1L;
2204 Update_List[Num_Updates].event = ev; /* flag event variable 0, 1 or 2 */
2205 if (0L != ev) {
2206 Update_List[Num_Updates].constant = false; /* an event is never a constant */
2207 } else {
2208 Update_List[Num_Updates].constant = MAYBE; /* not yet determined */
2209 }
2210 Segment_List[Num_Segments-1].used1 = true;
2211 for (d = 0L; d < MAXDEPTH; d++) {
2212 Update_List[Num_Updates].mline[d] = mline[d]; /* record line for identification */
2213 Update_List[Num_Updates].mfile[d] = mfile[d]; /* record file for identification */
2214 }
2215 increment_update_number(instruction);
2216 return;
2217}
#define NOT_INSTRUCTION(x)
Definition lp.c:74
#define INSTRUCTION(x)
Definition lp.c:73

References clean_parentheses(), get_sign_and_token(), get_token_between_braces(), increment_update_number(), INSTRUCTION, is_an_identifier(), ISEMPTY, ISNOTEMPTY, MAXDEPTH, MAYBE, node_id(), NOT_INSTRUCTION, Num_Segments, Num_Updates, print_error_location(), resolve_pathnames(), Segment_List, STDERR, strcpy_alloc(), STRLENGTH, UNDEFINED, Update_Flag, and Update_List.

Referenced by get_event(), get_var(), and line_parsing().

◆ get_var()

void get_var ( char * str,
const char * instruction )

Definition at line 965 of file lp.c.

965 {
966
967 /* INSTRUCTION: DVAR, IVAR, EVENT, STRING */
968 /* - variable name mandatory, unsigned, unique */
969 /* - parameters optional when compiling a standalone simulator. no self-reference is allowed */
970 /* - short forms accepted: &export, and for ivar and dvar, &update and &const */
971
972 /* string is not behaving like other variables! They are true constant and not sorted */
973
974 /* Parameters of these variables are stored in tables for */
975 /* further processing */
976 char tok1[STRLENGTH] = {'\0'};
977 char tok2[STRLENGTH] = {'\0'};
978 char tok3[STRLENGTH] = {'\0'};
979 char tok4[STRLENGTH] = {'\0'};
980 char tok5[STRLENGTH] = {'\0'};
981 char tok6[STRLENGTH] = {'\0'};
982 char tok7[STRLENGTH] = {'\0'};
983 char brc[3] = {'\0'};
984 char sgn[2] = {'\0'};
985 char *s = (char*) NULL;
986 char *t = (char*) NULL;
987 long d, k, v, i, j;
988 int ev;
989 int flag, cflag, eflag, uflag;
990
991 flag = false;
992 cflag = false;
993 eflag = false;
994 uflag = false;
995 s = get_token_between_braces(str, brc, tok2);
996 if (0 == strcmp(brc, "")) {
997 str = get_sign_and_token(str, sgn, tok1); /* var_name */
998 } else if (0 == strcmp(brc, "()")) {
999 flag = true; /* do not care of variable usage */
1000 str = s;
1001 s = tok2;
1002 s = get_sign_and_token(s, sgn, tok1); /* var_name */
1003 } else {
1004 print_error_location(instruction, mline, mfile);
1005 (void) fprintf(STDERR, " brackets, if any, around variable name cannot be < %s > but parenthesis\n", brc);
1006 return;
1007 }
1008 if (!is_an_identifier(tok1)) {
1009 print_error_location(instruction, mline, mfile);
1010 (void) fprintf(STDERR, " %s name <%s> is not a NAPA identifier\n", instruction, tok1);
1011 return;
1012 }
1013 if (ISNOTEMPTY(sgn)) {
1014 print_error_location(instruction, mline, mfile);
1015 (void) fprintf(STDERR, " no sign expected in front of the %s identifier <%s>\n", instruction, tok1);
1016 return;
1017 }
1018 if (ISEMPTY(tok1)) {
1019 print_error_location(instruction, mline, mfile);
1020 (void) fprintf(STDERR, " %s name is missing\n", instruction);
1021 return;
1022 }
1023 if ((char*) NULL != strchr(tok1, ':')) {
1024 print_error_location(instruction, mline, mfile);
1025 (void) fprintf(STDERR, " definition of %s <%s> cannot include a bit field\n", instruction, tok1);
1026 return;
1027 }
1028 if (0 == strcmp(tok1, "fs")) { /* not catched by is_a_keyword() function */
1029 print_error_location(instruction, mline, mfile);
1030 (void) fprintf(STDERR, " %s identifier cannot be the <fs> identifier\n", instruction );
1031 return;
1032 }
1033 if (0 == strcmp(tok1, "void")) { /* not catched by is_a_keyword() function */
1034 print_error_location(instruction, mline, mfile);
1035 (void) fprintf(STDERR, " %s identifier cannot be the <void> identifier\n", instruction );
1036 return;
1037 }
1038 k = is_a_keyword(tok1);
1039 if (ERROR == k) {
1040 print_error_location(instruction, mline, mfile);
1041 (void) fprintf(STDERR, " keyword <%s> cannot be used as %s identifier\n", tok1, instruction);
1042 /* parsing of instruction may continue */
1043 }
1044 if (WARNING == k) {
1045 print_warning_location(instruction, mline, mfile);
1046 (void) fprintf(STDERR, " keyword <%s> is not recommended to be used as %s name\n", tok1, instruction);
1047 }
1048 i = var_id(tok1);
1049 if (UNDEFINED != i) {
1050 print_error_location(instruction, mline, mfile);
1051 (void) fprintf(STDERR, " %s variable definition!<%s> is already defined\n", instruction, tok1);
1052 print_location(Var_List[i].mline, Var_List[i].mfile);
1053 return;
1054 }
1055 i = alias_id(tok1);
1056 if (UNDEFINED != i) {
1057 print_error_location(instruction, mline, mfile);
1058 (void) fprintf(STDERR, " %s definition <%s> is colliding an alias defined\n", instruction, tok1);
1059 print_location(Alias_List[i].mline, Alias_List[i].mfile);
1060 /* parsing of instruction may continue */
1061 }
1062 i = node_id(tok1);
1063 if (UNDEFINED != i) {
1064 print_error_location(instruction, mline, mfile);
1065 (void) fprintf(STDERR, " %s definition <%s> is colliding a node defined\n", instruction, tok1);
1066 print_location(Node_List[i].mline, Node_List[i].mfile);
1067 return;
1068 }
1069 i = record_id(tok1);
1070 if (UNDEFINED != i) {
1071 print_error_location(instruction, mline, mfile);
1072 (void) fprintf(STDERR, " %s definition <%s> is colliding a record defined\n", instruction, tok1);
1073 print_location(Record_List[i].mline, Record_List[i].mfile);
1074 return;
1075 }
1076 i = array_id(tok1);
1077 if (UNDEFINED != i) {
1078 print_error_location(instruction, mline, mfile);
1079 (void) fprintf(STDERR, " %s definition <%s> is colliding an array defined\n", instruction, tok1);
1080 print_location(Array_List[i].mline, Array_List[i].mfile);
1081 return;
1082 }
1083 i = directive_id(tok1);
1084 if (UNDEFINED != i) {
1085 print_error_location(instruction, mline, mfile);
1086 (void) fprintf(STDERR, " %s definition <%s> is colliding a directive defined\n", instruction, tok1);
1087 print_location(Directive_List[i].mline, Directive_List[i].mfile);
1088 return;
1089 }
1090 t = strstr(str, "&update"); /* detect the presence of short form '&update' */
1091 if ((char*) NULL != t) {
1092 uflag = true;
1093 for (i = 0L; i < 6L; i++) { /* clear processed '&update' from instruction */
1094 *t++ = ' ';
1095 }
1096 *t = ' ';
1097 }
1098 t = strstr(str, "&constant"); /* detect the presence of short form '&constant' */
1099 if ((char*) NULL != t) {
1100 cflag = true;
1101 for (i = 0; i < 8; i++) { /* clear processed '&constant' from instruction */
1102 *t++ = ' ';
1103 }
1104 *t = ' ';
1105 }
1106 t = strstr(str, "&export"); /* detect the presence of short form '&export' */
1107 if ((char*) NULL != t) {
1108 eflag = true;
1109 for (i = 0L; i < 6L; i++) { /* clear processed '&export' from instruction */
1110 *t++ = ' ';
1111 }
1112 *t = ' ';
1113 }
1114 (void) strcpy(tok4, str); /* var value without &export, &update, &constant */
1115 for (j = 0L; j <= LENGTH(tok4); j++) { /* process value as a comment: clear double quotes */
1116 if ('"' == tok4[j]) {
1117 tok4[j] = ' ';
1118 }
1119 }
1120
1121 if (INSTRUCTION("dvar")) { /* ***** ANALOG ***** */
1122 if (0 == strcmp("Space", tok1)) {
1123 print_error_location(instruction, mline, mfile);
1124 (void) fprintf(STDERR, " variable <%s> must be a string and cannot being defined as analog\n", tok1);
1125 /* parsing of instruction may continue */
1126 }
1128 if (eflag) {
1129 get_export(tok1); /* ask for export of this dvar */
1130 }
1131 if (uflag) {
1132 get_update(tok1, "dvar"); /* ask for update of this dvar */
1133 }
1134 if (cflag) {
1135 (void) snprintf(tok6, (size_t) (STRLENGTH-1L), " (constant) %s ", tok1);
1136 get_declare(tok6); /* ask for a constant declaration about this dvar */
1137 }
1138 ev = 0; /* this is not an event */
1139 clean_parentheses(str);
1140 resolve_pathnames(str, depth); /* resolve pathname using conventions */
1141 strcpy_alloc(&(Var_List[Num_Vars].value), str, mline, mfile); /* store the value of the dvar variable */
1142 strcpy_alloc(&(Var_List[Num_Vars].comment), tok4, mline, mfile); /* store comment for command_line documentation */
1143 if (0L != width) {
1144 print_error_location(instruction, mline, mfile);
1145 (void) fprintf(STDERR, " variable <%s>, being analog, cannot be width limited\n", tok1);
1146 /* parsing of instruction may continue */
1147 }
1148 Var_List[Num_Vars].width = 0L;
1149
1150 } else if (INSTRUCTION("ivar")) { /* ***** DIGITAL ***** */
1151 if (0 == strcmp("Space", tok1)) {
1152 print_error_location(instruction, mline, mfile);
1153 (void) fprintf(STDERR, " variable <%s> must be a string and cannot being defined as digital\n", tok1);
1154 /* parsing of instruction may continue */
1155 }
1157 if (eflag) {
1158 get_export(tok1); /* ask for export of this ivar */
1159 }
1160 if (uflag) {
1161 get_update(tok1, "ivar"); /* ask for update of this ivar */
1162 }
1163 if (cflag) {
1164 (void) snprintf(tok6, (size_t) (STRLENGTH-1L), " (constant) %s ", tok1);
1165 get_declare(tok6); /* ask for a declaration about this ivar */
1166 }
1167 ev = 0; /* this is not an event */
1168 clean_parentheses(str);
1169 resolve_pathnames(str, depth); /* resolve pathname using conventions */
1170 strcpy_alloc(&(Var_List[Num_Vars].value), str, mline, mfile); /* store the value of the ivar variable */
1171 strcpy_alloc(&(Var_List[Num_Vars].comment), tok4, mline, mfile); /* store comment for command_line documentation */
1172 Var_List[Num_Vars].width = width;
1173
1174 } else if (INSTRUCTION("event")) { /* ***** EVENT ***** */
1175 if (0 == strcmp("Space", tok1)) {
1176 print_error_location(instruction, mline, mfile);
1177 (void) fprintf(STDERR, " variable <%s> must be a string and cannot being defined as an event\n", tok1);
1178 /* parsing of instruction may continue */
1179 }
1181 if (eflag) {
1182 get_export(tok1); /* ask for export of this event */
1183 }
1184 if (uflag) {
1185 print_error_location(instruction, mline, mfile);
1186 (void) fprintf(STDERR, " redundant update, an event is automatically updated by definition\n");
1187 /* parsing of instruction may continue, error as processing of event causes C compiler error with spurious &update token */
1188 }
1189 if (cflag) {
1190 print_error_location(instruction, mline, mfile);
1191 (void) fprintf(STDERR, " an event variable cannot be constant\n");
1192 /* parsing of instruction may continue */
1193 }
1194 clean_parentheses(str);
1195 resolve_pathnames(str, depth); /* resolve pathname using conventions */
1196 (void) strcpy(tok7, str);
1197 s = get_token_between_braces(str, brc, tok5); /* test first text between () */
1198 if ((0 == strcmp(brc, "()")) && (0 == strcmp(tok5, "new"))) {
1199 ev = 2; /* event tagged with '(new)' modifier */
1200 } else {
1201 ev = 1; /* this is a regular event without (new) qualifier */
1202 (void) strcpy(s, tok7);
1203 }
1204 (void) strcpy(tok3, "(I_TYPE) ("); /* cast the boolean result to I_TYPE */
1205 (void) strcat(tok3, s);
1206 (void) strcat(tok3, ")");
1207 (void) strcpy(str, tok3);
1208 strcpy_alloc(&(Var_List[Num_Vars].value), str, mline, mfile); /* store the value of the event variable */
1209 strcpy_alloc(&(Var_List[Num_Vars].comment), tok4, mline, mfile);
1210 if (0L != width) {
1211 print_error_location(instruction, mline, mfile);
1212 (void) fprintf(STDERR, " event variable <%s> cannot be width limited\n", tok1);
1213 /* parsing of instruction may continue */
1214 }
1215 Var_List[Num_Vars].width = 0L;
1216 flag = true; /* no care of event variable usage */
1217
1218 } else { /* ***** STRING ***** */
1220 if (eflag) {
1221 get_export(tok1); /* ask for export of this string */
1222 }
1223 if (uflag) {
1224 print_error_location(instruction, mline, mfile);
1225 (void) fprintf(STDERR, " a string cannot be updated\n");
1226 /* parsing of instruction may continue */
1227 }
1228 if (cflag) {
1229 print_warning_location(instruction, mline, mfile);
1230 (void) fprintf(STDERR, " redundant declaration as a string is always constant\n");
1231 }
1232 ev = 0; /* this is not an event */
1233 if (ISEMPTY(str)) {
1234 (void) strcat(str, "\" \"");
1235 if (ISEMPTY(tok2)) { /* empty definition: generate a unique identifier */
1236 (void) snprintf(tok2, (size_t) (STRLENGTH-1L), "\"%s\"", unique_name());
1237 (void) strcpy(str, tok2); /* replace the empty string */
1238 strcpy_alloc(&(Var_List[Num_Vars].value), tok2, mline, mfile); /* store the string constant */
1239 }
1240 }
1241 if (ISNOTEMPTY(str)) {
1242 if ('"' == str[0]) { /* value is a string constant between double quotes */
1243 str = get_token(str, tok2, true);
1244 resolve_pathnames(tok2, depth);
1245 strcpy_alloc(&(Var_List[Num_Vars].value), tok2, mline, mfile); /* store the string constant */
1246 } else { /* value is another string variable */
1247 str = get_token(str, tok2, false); /* first token is the variable id */
1248 v = var_id(tok2);
1249 if ((UNDEFINED == v) || (STRING_DATA_TYPE != Var_List[v].type)) { /* not a string variable */
1250 print_error_location(instruction, mline, mfile);
1251 (void) fprintf(STDERR, " identifier <%s> is not defined previously as a string variable\n", tok2);
1252 return;
1253 }
1254 strcpy_alloc(&(Var_List[Num_Vars].value), Var_List[v].value, mline, mfile); /* store the value of the string variable */
1255 }
1256 }
1257 strcpy_alloc(&(Var_List[Num_Vars].comment), tok4, mline, mfile); /* store comment for command_line documentation */
1258 if (0L != width) {
1259 print_error_location(instruction, mline, mfile);
1260 (void) fprintf(STDERR, " string variable <%s> cannot be width limited\n", tok1);
1261 /* parsing of instruction may continue */
1262 }
1263 Var_List[Num_Vars].width = 0L; /* no width for a string */
1264 flag = true; /* no care of string variable usage */
1265 }
1266
1267 strcpy_alloc(&(Var_List[Num_Vars].name1), tok1, mline, mfile); /* variable name */
1268 strcpy_alloc(&(Var_List[Num_Vars].name2), tok1, mline, mfile); /* copy of var name */
1269 Var_List[Num_Vars].aliased = false; /* not aliased yet */
1270 Var_List[Num_Vars].declare = UNKNOWN_TYPE; /* not yet declared */
1271 Var_List[Num_Vars].used = flag; /* variable usage */
1272 Var_List[Num_Vars].external = false; /* not known as a command line parm */
1273 Var_List[Num_Vars].ID = Num_Vars; /* unique variable ID */
1274 Var_List[Num_Vars].segment = Num_Segments - 1L; /* record segment level */
1275 Var_List[Num_Vars].event = ev; /* flag event variable: 0, 1 or 2 */
1276 Var_List[Num_Vars].determined = false; /* not yet determined */
1277 Var_List[Num_Vars].constant = MAYBE; /* not yet determined */
1278 for (d = 0L; d < MAXDEPTH; d++) {
1279 Var_List[Num_Vars].mline[d] = mline[d]; /* record line for identification */
1280 Var_List[Num_Vars].mfile[d] = mfile[d]; /* record file for identification */
1281 }
1282 for (;;) { /* check for var self-referencing */
1283 str = get_sign_and_token(str, sgn, tok1);
1284 if (ISEMPTY(tok1)) {
1285 break;
1286 }
1287 if (0 == strcmp(tok1, Var_List[Num_Vars].name1)) {
1288 print_error_location(instruction, mline, mfile);
1289 (void) fprintf(STDERR, " <%s> self-reference is not allowed in a %s definition\n", Var_List[Num_Vars].name1, instruction);
1290 /* parsing of instruction may continue */
1291 break;
1292 }
1293 }
1294 increment_var_number(instruction);
1295 return;
1296}
void get_export(const char *str)
Definition lp.c:3662
void get_declare(char *str)
Definition lp.c:2679
char * unique_name(void)
Definition tk.c:1766

References alias_id(), Alias_List, ANALOG_DATA_TYPE, array_id(), Array_List, clean_parentheses(), DIGITAL_DATA_TYPE, directive_id(), Directive_List, ERROR, get_declare(), get_export(), get_sign_and_token(), get_token(), get_token_between_braces(), get_update(), increment_var_number(), INSTRUCTION, is_a_keyword(), is_an_identifier(), ISEMPTY, ISNOTEMPTY, LENGTH, MAXDEPTH, MAYBE, node_id(), Node_List, Num_Segments, Num_Vars, print_error_location(), print_location(), print_warning_location(), record_id(), Record_List, resolve_pathnames(), STDERR, strcpy_alloc(), STRING_DATA_TYPE, STRLENGTH, UNDEFINED, unique_name(), UNKNOWN_TYPE, var_id(), Var_List, and WARNING.

Referenced by get_event(), and line_parsing().

◆ get_void()

void get_void ( char * str)

Definition at line 2362 of file lp.c.

2362 {
2363
2364 /* INSTRUCTION: VOID */
2365 /* - stream name mandatory */
2366 /* <...> pathname is pointing to the header directory */
2367
2368 char tok1[STRLENGTH] = {'\0'};
2369 char tok2[STRLENGTH] = {'\0'};
2370 char tok3[STRLENGTH] = {'\0'};
2371 char brc[3] = {'\0'};
2372 char *p = (char*) NULL;
2373 if (data_flag[depth]) {
2374 print_error_location("data", mline, mfile);
2375 (void) fprintf(STDERR, " instruction 'void' is not allowed in a data cell file\n");
2376 return;
2377 }
2378 if (0L != width) {
2379 print_warning_location("void", mline, mfile);
2380 (void) fprintf(STDERR, " this instruction cannot be width limited\n");
2381 }
2382 str = get_token_between_braces(str, brc, tok2); /* process following NAPA file system */
2383 if (ISEMPTY(tok2)) {
2384 print_error_location("void", mline, mfile);
2385 (void) fprintf(STDERR, " file name is missing\n");
2386 return;
2387 }
2388 build_pathname(brc, tok2, Header_Lib_Name, mline, mfile);
2389 (void) strcpy(tok3, Cur_Lib_Name[depth]); /* do not modify Cur_Lib_Name[] */
2390 extract_directory(tok3, tok2, depth); /* there is no record of new pathname */
2391 (void) snprintf(tok1, (size_t) (STRLENGTH-1L), "%s%s", tok3, tok2);
2392 if (1L <= LENGTH(str)) {
2393 print_error_location("void", mline, mfile);
2394 (void) fprintf(STDERR, " too many parameters <%s %s> for this instruction\n", tok1, str);
2395 return;
2396 }
2397 p = tok1;
2399 (void) strcpy(Void_List_Name, p); /* filename without "" */
2400 return;
2401}

References build_pathname(), Cur_Lib_Name, extract_directory(), get_token_between_braces(), Header_Lib_Name, ISEMPTY, LENGTH, print_error_location(), print_warning_location(), simplify_pathname(), STDERR, STRLENGTH, and Void_List_Name.

Referenced by line_parsing().

◆ inspect_short_form()

void inspect_short_form ( const char * instruction,
char * string,
const char * tok )

Definition at line 5202 of file lp.c.

5202 { /* check validity of presence of a short form */
5203 char *t = (char*) NULL;
5204
5205 if (0 == strcmp(instruction, "node")) {
5206 t = strstr(string, "&update");
5207 if ((char*) NULL != t) {
5208 print_error_location(instruction, mline, mfile);
5209 (void) fprintf(STDERR, " a node accepts only the short form '&delayed'\n");
5211 }
5212 t = strstr(string, "&constant");
5213 if ((char*) NULL != t) {
5214 print_error_location(instruction, mline, mfile);
5215 (void) fprintf(STDERR, " a node accepts only the short form '&delayed'\n");
5217 }
5218 t = strstr(string, "&export");
5219 if ((char*) NULL != t) {
5220 print_error_location(instruction, mline, mfile);
5221 (void) fprintf(STDERR, " the short form '&export' cannot be used for a node, use the explicit instruction 'export'\n");
5223 }
5224 return;
5225 }
5226
5227 if (0 == strcmp(tok, "&delayed")) {
5228 t = strstr(string, "&delayed");
5229 if ((char*) NULL != t) {
5230 print_error_location(instruction, mline, mfile);
5231 (void) fprintf(STDERR, " this instruction does not accept the short form '&delayed'\n" );
5233 }
5234 return;
5235 }
5236
5237 if (0 == strcmp(tok, "&any")) {
5238 t = strstr(string, "&delayed");
5239 if ((char*) NULL != t) {
5240 print_error_location(instruction, mline, mfile);
5241 (void) fprintf(STDERR, " this instruction does not accept the short form '&delayed'\n" );
5243 }
5244 t = strstr(string, "&update");
5245 if ((char*) NULL != t) {
5246 print_error_location(instruction, mline, mfile);
5247 (void) fprintf(STDERR, " this instruction does not accept the short form '&update'\n" );
5249 }
5250 t = strstr(string, "&constant");
5251 if ((char*) NULL != t) {
5252 print_error_location(instruction, mline, mfile);
5253 (void) fprintf(STDERR, " this instruction does not accept the short form '&constant'\n");
5255 }
5256 t = strstr(string, "&export");
5257 if ((char*) NULL != t) {
5258 print_error_location(instruction, mline, mfile);
5259 (void) fprintf(STDERR, " this instruction does not accept the short form '&export'\n" );
5261 }
5262 }
5263 return;
5264}

References print_error_banner_and_exit(), print_error_location(), and STDERR.

Referenced by line_parsing().

◆ line_parsing()

void line_parsing ( void )

Definition at line 118 of file lp.c.

118 {
119 long d, i, j, n;
120 unsigned long nl = 0UL;
121 char *p = (char*) NULL;
122 char *s = (char*) NULL;
123 char *t = (char*) NULL;
124 char *string = (char*) NULL;
125 char brc[3] = {'\0'};
126 char cell_name[STRLENGTH] = {'\0'};
127 char token[STRLENGTH] = {'\0'};
128 char instruction[STRLENGTH] = {'\0'};
129 char old_instruction[STRLENGTH] = {'\0'};
130 char buffer1[LINLENGTH] = {'\0'};
131 char buffer2[LINLENGTH] = {'\0'};
132 char buffer3[LINLENGTH] = {'\0'};
133 long errors;
134 errors = 0L;
135 (void) strcpy(instruction, "");
136 (void) strcpy(old_instruction, "");
137 for (d = 0L; d < MAXDEPTH; d++) { /* reset hierarchical line & file numbering */
138 mline[d] = 0UL; /* line 0 for every depth */
139 mfile[d] = 0UL; /* file 0 for every depth, i.e. main netlist */
140 }
141 increment_segment_number("main segment"); /* first segment exists by default */
142 depth = 0L; /* set hierarchy depth to 0 i.e. main file */
143 (void) strcpy(Cell_Name_Prefix[0], ""); /* main file nodes have no cell prefix name */
144 data_flag[0] = false; /* main file is not a data file */
145 (void) strcpy(Cur_Fil_Name[0], Main_File_Name);
146 (void) strcpy(Cur_Lib_Name[0], "./");
147 record_file_nam(0, mline, mfile); /* record main file name at depth 0 */
148 if (Expand_Flag) {
149 (void) fprintf(STDERR, "\nNAPA File Expansion:\n");
150 (void) fprintf(STDERR, " Input files are expanded as requested.\n");
151 (void) fprintf(STDERR, " No C file has been created.\n\n");
152 n = fprintf(STDOUT, "\n#* ***** EXPANSION OF FILE %s ", Main_File_Name);
153 (void) fprintf(STDERR, "\n********* EXPANSION *************");
154 n = MAX(117L - n, 0L);
155 (void) f2printf(STDERR, STDOUT, "%s", multiple('*', n));
156 (void) fprintf(STDOUT, " START *******\n\n\n");
157 (void) fprintf(STDERR, " START *******\n\n");
158 }
159 /* open main file */
160 fhandle[0] = fopen(Cur_Fil_Name[0], "r");
161 if ((FILE*) NULL == fhandle[0]) {
162 print_error_location("file", mline, mfile);
163 (void) fprintf(STDERR, " OUCH!- can't find or access main netlist file <\"%s\">\n", Cur_Fil_Name[0]);
164 exit(EXIT_FAILURE);
165 }
166 Segment_List[0].type = MAIN_SEGMENT_TYPE; /* segment 0 is the main segment */
167 Segment_List[0].offset = 0.0;
168 Segment_List[0].rate = 1.0;
169 Segment_List[0].used1 = false; /* initialize to detect future usage */
170 Segment_List[0].used2 = false;
171 Segment_List[0].used3 = false;
172 Segment_List[0].periodic = true;
173 /* set-up of control and state variables is done, the processing of the user's file may start. */
174 p = get_a_line(buffer1, &nl, fhandle[0], mline, mfile); /* read 1st line of main netlist */
175 if ((char*) NULL == p) {
176 print_error_location("file", mline, mfile);
177 (void) fprintf(STDERR, " main netlist file <\"%s\"> is empty or corrupted\n", Cur_Fil_Name[0]);
178 exit(EXIT_FAILURE);
179 }
180
181 /* line by line scan and process */
182
183 while ((char*) NULL != p) {
184 mline[depth] += nl; /* line numbering for error documentation */
185 sanity_check(buffer1, mline, mfile); /* check parenthesis, brackets, ... */
186 process_cell_line(buffer1, depth, mline, mfile); /* replace local cell nodes */
187 if (Expand_Flag) {
188 (void) strcpy(buffer3, buffer1); /* for expansion, save the content of the buffer */
189 }
190 string = buffer1; /* line preprocessed */
191 string = get_token_between_braces(string, brc, token); /* bit width if any */
192 string = get_token(string, instruction, false); /* extract instruction keyword */
193 width = process_width(brc, token, instruction); /* zero <=> 'unlimited' width */
194 pseudonode = UNKNOWN_KIND; /* to flag cell or generator node */
195
196 if (INSTRUCTION("" )) { /* blank line */
197 /* do nothing */
198
199 } else if (INSTRUCTION("node" )) { /* node_keyword node_name node_kind node_val */
200 inspect_short_form(instruction, string, ""); /* specific check for nodes, will accept '&delayed' */
201 string = get_node(string, token, &pseudonode); /* postprocess of line follows (cell or generator) */
202
203 } else if (INSTRUCTION("tool" )) { /* 'tool ...' is equivalent to 'node void itool...' */
204 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
205 (void) snprintf(buffer2, (size_t) (LINLENGTH-1L), "void itool %s", string); /* expanding this short form in a node 'itool' */
206 t = buffer2;
207 string = get_node(t, token, &pseudonode);
208
209 } else if (INSTRUCTION("dvar" )
210 || INSTRUCTION("ivar" )) { /* var_keyword var_name var_value */
211 inspect_short_form(instruction, string, "&delayed"); /* do not accept short form '&delayed' */
212 get_var(string, instruction);
213
214 } else if (INSTRUCTION("string" )) { /* string_keyword var_name var_value */
215 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
216 get_var(string, instruction);
217
218 } else if (INSTRUCTION("header" )) { /* header_keyword header_name */
219 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
220 get_header(string);
221
222 } else if (INSTRUCTION("directive" )) { /* directive_keyword name value */
223 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
224 get_directive(string);
225
226 } else if (INSTRUCTION("decimate" )) { /* decimate_keyword [fs] num_decim [num_off] */
227 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
228 get_decimate(string);
229
230 } else if (INSTRUCTION("nominal" )) { /* nominal_keyword fs */
231 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
232 get_nominal(string);
233
234 } else if (INSTRUCTION("interpolate" )) { /* keyword interpolate_num */
235 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
236 get_interpolate(string);
237
238 } else if (INSTRUCTION("drop" )) { /* drop_keyword drop_condition */
239 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
240 get_drop(string);
241
242 } else if (INSTRUCTION("event" )) { /* keyword event_definition */
243 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
244 get_event(string);
245
246 } else if (INSTRUCTION("command_line")) { /* command_line keyword list */
247 get_command_line(string);
248
249 } else if (INSTRUCTION("update" )) { /* update_keyword var_name update_value */
250 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
251 get_update(string, instruction);
252
253 } else if (INSTRUCTION("output" )) { /* output_keyword out_filename output_list */
254 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
255 get_output(string);
256
257 } else if (INSTRUCTION("input" )) { /* input_keyword in_filename input_list */
258 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
259 get_input(string);
260
261 } else if (INSTRUCTION("void" )) { /* void_keyword filename */
262 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
263 get_void(string);
264
265 } else if (INSTRUCTION("terminate" )) { /* terminate_keyword */
266 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
267 get_terminate(string);
268
269 } else if (INSTRUCTION("synchronize" )) { /* synchro_keyword name value */
270 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
271 get_synchronize(string);
272
273 } else if (INSTRUCTION("init" )) { /* init_keyword init_value */
274 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
275 get_init(string);
276
277 } else if (INSTRUCTION("declare" )) { /* declare_keyword node_name qualifier */
278 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
279 get_declare(string);
280
281 } else if (INSTRUCTION("interlude" )) { /* interlude_keyword value1 (value2) */
282 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
283 get_interlude(string);
284
285 } else if (INSTRUCTION("num_initial" )) { /* deprecated */
286 print_warning_location("num_initial", mline, mfile);
287 (void) fprintf(STDERR, " 'num_initial' is deprecated, replaced by 'interlude' instruction\n");
288 get_interlude(string);
289
290 } else if (INSTRUCTION("random_seed" )) { /* random_seed_keyword seed_initial_value */
291 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
292 get_random_seed(string);
293
294 } else if (INSTRUCTION("title" )) { /* title_keyword title_value */
295 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
296 get_title(string);
297
298 } else if (INSTRUCTION("export" )) { /* export_keyword export_name */
299 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
300 get_export(string);
301
302 } else if (INSTRUCTION("fs" )) { /* fs_keyword fs_value */
303 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
304 get_fs_ts(string, 1);
305
306 } else if (INSTRUCTION("ts" )) { /* ts_keyword ts_value */
307 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
308 get_fs_ts(string, 0);
309
310 } else if (INSTRUCTION("data" )) { /* data_keyword file_name data_interface */
311 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
312 get_data(string, buffer1, cell_name);
313
314 } else if (INSTRUCTION("alias" )) { /* alias_ name target */
315 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
316 get_alias(string);
317
318 } else if (INSTRUCTION("array" )) { /* array_keyword name [size] (variant) */
319 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
320 get_array("array", string);
321
322 } else if (INSTRUCTION("ganging" )) { /* ganging_keyword name [size] */
323 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
324 get_array("ganging", string);
325
326 } else if (INSTRUCTION("opcode" )) { /* opcode_keyword name number value */
327 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
328 get_opcode(string);
329
330 } else if (INSTRUCTION("debug" )) { /* debug_keyword optional_int */
331 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
332 get_debug(string);
333
334 } else if (INSTRUCTION("post" )) { /* postprocess_keyword optional_parms */
335 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
336 get_post(string);
337
338 } else if (INSTRUCTION("inject" )) { /* inject_keyword formula */
339 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
340 get_inject(string);
341
342 } else if (INSTRUCTION("napa_version")) { /* napa_version keyword version ID */
343 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
344 check_version(string);
345
346 } else if (INSTRUCTION("format" )) { /* (type) Format_of_Type_value */
347 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
348 get_format(string);
349
350 } else if (INSTRUCTION("assert" )) { /* assert_keyword assert_value */
351 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
352 get_assert(string);
353
354 } else if (INSTRUCTION("ping" )) { /* ping_keyword ping_value parameter */
355 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
356 get_ping(string);
357
358 } else if (INSTRUCTION("gateway" )) { /* gateway_keyword */
359 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
360 get_gateway(string);
361
362 } else if (INSTRUCTION("stuck" )) { /* stuck_keyword node_name stuck_value */
363 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
364 get_stuck(string);
365
366 } else if (INSTRUCTION("call" )) { /* call_keyword call_value */
367 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
368 get_call(string);
369
370 } else if (INSTRUCTION("restart" )) { /* restart_keyword */
371 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
372 get_restart(string);
373
374 } else if (INSTRUCTION("sampling" )) { /* sampling_keyword formula */
375 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
376 get_sampling(string);
377
378 } else if (INSTRUCTION("dump" )) { /* dump_keyword dump_File_Name condition */
379 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
380 get_dump(string);
381
382 } else if (INSTRUCTION("load" )) { /* load_keyword load_File_Name */
383 inspect_short_form(instruction, string, "&any"); /* do not accept any kind of short form */
384 get_load(string);
385
386 } else if (INSTRUCTION("comment" )) { /* comment line: string between quotes */
387 get_comment(string);
388
389 } else if (INSTRUCTION("warning" )) { /* warning line */
390 (void) fprintf(STDERR, "\n");
391 print_warning_location("information from parser", mline, mfile);
392 (void) fprintf(STDERR, "\n USER's MESSAGE collected during parsing:");
393 s = string;
394 s = get_token(s, token, false); /* text between string */
395 expand_indirections(token); /* expand on the fly, if possible */
396 (void) fprintf(STDERR, " < %s >\n\n", token);
397
398 } else if (INSTRUCTION("error" )) { /* error line, immediate processing */
399 print_error_location("information from parser", mline, mfile);
400 (void) fprintf(STDERR, "\n The parser is instructed by the user to prevent the\n");
401 (void) fprintf(STDERR, " simulation of this NAPA netlist in its current state:\n\n");
402 s = string;
403 s = get_token(s, token, false);
404 (void) fprintf(STDERR, " < %s >\n\n", token);
406
407 } else if (INSTRUCTION("cell_interface")) {
408 print_error_location("parser", mline, mfile);
409 (void) fprintf(STDERR, " cell interface is only allowed as head line of a cell\n");
411
412 } else {
413 print_error_location("parser", mline, mfile);
414 (void) fprintf(STDERR, " token <%s> is not a NAPA instruction\n", instruction);
415 if (!is_an_identifier(instruction)) {
416 (void) fprintf(STDERR, ", nor a well-formed NAPA identifier\n");
417 }
418 process_instruction_error(instruction); /* help user for spelling error */
419 errors++;
420 if (4L < errors) { /* avoid repetition of error messages */
422 }
423 /* process may continue */
424 }
425
426 if (Expand_Flag) { /* netlist expansion requested */
427 if (NOT_INSTRUCTION("") && NOT_INSTRUCTION("#") && NOT_INSTRUCTION("data")
428 && (CELL_KIND != pseudonode) && (GEN_KIND != pseudonode) && (SET_KIND != pseudonode)) {
429 if ((0 != strcmp(old_instruction, instruction)) && (0 != strcmp(old_instruction, ""))) {
430 (void) fprintf(STDOUT, "\n");
431 }
432 restore_line(buffer3); /* options (..) have been replaced by ..$ ! */
433 for (j = 0L; j < depth; j++) {
434 (void) fprintf(STDOUT, " "); /* indentation */
435 }
436 (void) fprintf(STDOUT, "%s\n", buffer3); /* copy; cell, generator, setnode, tool excepted */
437 (void) strcpy(old_instruction, instruction);
438 } else if (CELL_KIND == pseudonode) {
439 (void) fprintf(STDOUT, "\n#* ");
440 (void) fprintf(STDERR, " ");
441 for (j = 0L; j < depth; j++) {
442 (void) f2printf(STDERR, STDOUT, ">> ");
443 }
444 (void) fprintf(STDOUT, ">> %s\n\n", buffer3);
445 (void) fprintf(STDERR, ">> "); /* cell file name will be printed later */
446 (void) strcpy(old_instruction, "");
447 } else if (GEN_KIND == pseudonode) {
448 (void) fprintf(STDOUT, "\n#* ");
449 (void) fprintf(STDERR, " ");
450 for (j = 0L; j < depth; j++) {
451 (void) f2printf(STDERR, STDOUT, ">> ");
452 }
453 (void) fprintf(STDOUT, ">> %s\n\n", buffer3);
454 (void) fprintf(STDERR, ">> "); /* gen file name will be printed later */
455 (void) strcpy(old_instruction, "");
456 } else if (INSTRUCTION("data")) {
457 (void) strcpy(old_instruction, "");
458 }
459 }
460
461 /* pseudo-node postprocessing, variable 'string' and 'pseudonode' set by 'get_node()', 'token' contains the node name. */
462
463 if (GEN_KIND == pseudonode) { /* special process of generator node */
464 string = process_gen(string, &pseudonode, cell_name);
465 if (Expand_Flag) {
466 (void) fprintf(STDOUT, "#* changed in ... cell %s\n\n", string);
467 }
468 process_cell(string, token, &pseudonode, cell_name);
469 }
470
471 if (CELL_KIND == pseudonode) { /* special process of cell node */
472 process_cell(string, token, &pseudonode, cell_name);
473 }
474
475 if (0 != strcmp(instruction, "")) { /* ignore blank line */
476 (void) strcpy(Last_Instruction, instruction); /* record last instruction */
477 }
478
479 p = get_a_line(buffer1, &nl, fhandle[depth], mline, mfile); /* read a new line */
480 while (((char*) NULL == p) && (0L < depth)) {
481 mline[depth] = 0UL; /* reset line numbering on this level */
482 if (EOF == fclose(fhandle[depth])) { /* end of current file, going back to upper */
483 print_error_location("parser", mline, mfile);
484 (void) fprintf(STDERR, " OUCH!- can't close cell or data file opened during parsing\n");
486 }
487 if (Expand_Flag) {
488 (void) fprintf(STDOUT, "\n#* ");
489 (void) fprintf(STDERR, " ");
490 for (j = 0L; j < (depth-1L); j++) {
491 (void) f2printf(STDERR, STDOUT, "<< ");
492 }
493 (void) f2printf(STDERR, STDOUT, "<<\n\n");
494 (void) strcpy(old_instruction, "");
495 }
496 depth--;
497 p = get_a_line(buffer1, &nl, fhandle[depth], mline, mfile); /* next line of upper file */
498 }
499 }
500
501 /* end of line by line scan and process */
502
503 if (EOF == fclose(fhandle[depth])) { /* end of main netlist */
504 print_error_location("parser", mline, mfile);
505 (void) fprintf(STDERR, " OUCH!- can't close main netlist file opened during parsing\n");
507 }
509
510 /* fill title, if necessary, with mainfile name */
511
512 if (ISEMPTY(Title_String)) {
513 (void) strcpy(Title_String, Main_File_Name);
516 for (n = 0L; n < LENGTH(Title_String); n++) {
517 Title_String[n] = (char) toupper((int) Title_String[n]);
518 }
519 } else {
520 Title_Flag = true;
521 }
522
523 /* correct the definition of segment 0 if necessary */
524
525 if (!Periodic_Flag) { /* false when sampling_rate replaces fs */
526 Segment_List[0].rate = 0.0;
527 for (i = 0L; i < Num_Segments; i++) {
528 Segment_List[i].periodic = false;
529 }
530 }
531 if (Expand_Flag) {
532 if (!Hierarchy_Flag) {
533 (void) f2printf(STDERR, NULL, "[ Trivial case as the NAPA main netlist has no hierarchy ]\n\n");
534 }
535 (void) fprintf(STDOUT, "\n\n");
536 n = fprintf(STDOUT, "#* ***** EXPANSION OF FILE %s ", Main_File_Name);
537 (void) fprintf(STDERR, "*********************************");
538 n = MAX(117L - n, 0L);
539 (void) f2printf(STDERR, STDOUT, "%s", multiple('*', n));
540 (void) f2printf(STDERR, STDOUT, "* END *******\n\n");
541
542 exit(EXIT_SUCCESS);
543 }
544
545 return;
546}
char * process_gen(char *str, long *pseudo, char *cell)
Definition lp.c:4560
void get_opcode(char *str)
Definition lp.c:4119
void get_output(char *str)
Definition lp.c:2220
void get_input(char *str)
Definition lp.c:2291
void get_title(char *str)
Definition lp.c:3622
void get_ping(char *str)
Definition lp.c:3197
void get_alias(char *str)
Definition lp.c:2404
void get_post(char *str)
Definition lp.c:1319
void get_random_seed(const char *str)
Definition lp.c:3584
void get_restart(const char *str)
Definition lp.c:3086
void get_array(const char *variant, char *str)
Definition lp.c:3695
void get_nominal(char *str)
Definition lp.c:1795
void trap_unconsistencies(void)
Definition lp.c:5269
void get_drop(char *str)
Definition lp.c:2015
void get_data(char *str, const char *buffer, char *cell)
Definition lp.c:4309
void process_cell(char *str, const char *nodnam, long *pseudo, char *cell)
Definition lp.c:4724
void get_event(const char *str)
Definition lp.c:1299
long process_width(const char *brc, const char *tok, const char *instr)
Definition lp.c:4986
void get_interlude(char *str)
Definition lp.c:3452
void get_void(char *str)
Definition lp.c:2362
void get_load(char *str)
Definition lp.c:4248
void get_stuck(char *str)
Definition lp.c:2907
void get_dump(char *str)
Definition lp.c:4168
void get_sampling(char *str)
Definition lp.c:3402
void get_gateway(char *str)
Definition lp.c:2860
void get_inject(char *str)
Definition lp.c:2978
void get_command_line(char *str)
Definition lp.c:2069
void get_comment(const char *str)
Definition lp.c:3254
void get_synchronize(char *str)
Definition lp.c:2599
void check_version(const char *str)
Definition lp.c:551
void get_terminate(char *str)
Definition lp.c:2559
void get_directive(char *str1)
Definition lp.c:1661
void get_fs_ts(char *str, long fs1ts0)
Definition lp.c:3293
void get_format(char *str)
Definition lp.c:3907
void get_call(char *str)
Definition lp.c:3039
void get_decimate(char *str)
Definition lp.c:1836
void get_interpolate(char *str)
Definition lp.c:1940
void get_assert(char *str)
Definition lp.c:2804
void get_debug(char *str)
Definition lp.c:3126
void get_header(char *str)
Definition lp.c:1577
void inspect_short_form(const char *instruction, char *string, const char *tok)
Definition lp.c:5202
void get_init(char *str)
Definition lp.c:2634
void process_instruction_error(const char *instr)
Definition mp.c:56
#define MAIN_SEGMENT_TYPE
Definition napa.h:349
EXTERN char * Main_File_Name
Definition napa.h:911
void strip_extension(char *fnam)
Definition tk.c:1598
void process_cell_line(char *buf, long d, const unsigned long *mlin, const unsigned long *mfil)
Definition tk.c:441
void restore_line(char *lin)
Definition tk.c:1452
char * multiple(char c, long n)
Definition tk.c:1801
void sanity_check(char *s, const unsigned long *mlin, const unsigned long *mfil)
Definition sx.c:1758
void expand_indirections(char *str)
Definition tk.c:717

References CELL_KIND, Cell_Name_Prefix, check_version(), Cur_Fil_Name, Cur_Lib_Name, drop_pathname(), Expand_Flag, expand_indirections(), f2printf(), GEN_KIND, get_a_line(), get_alias(), get_array(), get_assert(), get_call(), get_command_line(), get_comment(), get_data(), get_debug(), get_decimate(), get_declare(), get_directive(), get_drop(), get_dump(), get_event(), get_export(), get_format(), get_fs_ts(), get_gateway(), get_header(), get_init(), get_inject(), get_input(), get_interlude(), get_interpolate(), get_load(), get_node(), get_nominal(), get_opcode(), get_output(), get_ping(), get_post(), get_random_seed(), get_restart(), get_sampling(), get_stuck(), get_synchronize(), get_terminate(), get_title(), get_token(), get_token_between_braces(), get_update(), get_var(), get_void(), Hierarchy_Flag, increment_segment_number(), inspect_short_form(), INSTRUCTION, is_an_identifier(), ISEMPTY, Last_Instruction, LENGTH, LINLENGTH, Main_File_Name, MAIN_SEGMENT_TYPE, MAX, MAXDEPTH, multiple(), NOT_INSTRUCTION, Num_Segments, Periodic_Flag, print_error_banner_and_exit(), print_error_location(), print_warning_location(), process_cell(), process_cell_line(), process_gen(), process_instruction_error(), process_width(), record_file_nam(), restore_line(), sanity_check(), Segment_List, SET_KIND, STDERR, STDOUT, strip_extension(), STRLENGTH, Title_Flag, Title_String, trap_unconsistencies(), and UNKNOWN_KIND.

Referenced by main().

◆ process_cell()

void process_cell ( char * str,
const char * nodnam,
long * pseudo,
char * cell )

Definition at line 4724 of file lp.c.

4724 {
4725
4726 /* PSEUDO NODE CELL PROCESSING */
4727 /* called after the processing of instruction "node" or pseudonode "generator" */
4728
4729 char cell_interface[LINLENGTH] = {'\0'}; /* 1st cell line */
4730 char inst_interface[LINLENGTH] = {'\0'}; /* cell call */
4731 char tok0[STRLENGTH] = {'\0'};
4732 char tok1[STRLENGTH] = {'\0'};
4733 char tok2[STRLENGTH] = {'\0'};
4734 char buff[LINLENGTH] = {'\0'};
4735 char brc[3] = {'\0'};
4736 char sgn1[2] = {'\0'};
4737 char sgn2[2] = {'\0'};
4738 char *str1 = (char*) NULL;
4739 char *str2 = (char*) NULL;
4740 time_t time_start;
4741 time_t time_stop;
4742 long v, i, j;
4743 unsigned long nl = 0UL;
4744
4745 (void) f1flush((FILE*) NULL); /* just in case during expansion */
4746
4747 if (data_flag[depth]) {
4748 print_error_location("data", mline, mfile);
4749 (void) fprintf(STDERR, " cell instantiations other than data cells are not allowed in a data cell file\n");
4751 }
4752 if (0L != width) {
4753 print_error_location("cell", mline, mfile);
4754 (void) fprintf(STDERR, " declaration of width is not allowed\n");
4755 /* parsing of instruction may continue */
4756 }
4757 str = get_token(str, cell, true); /* get cell instantiation name */
4758 if (ISEMPTY(cell)) {
4759 print_error_location("cell instantiation", mline, mfile);
4760 (void) fprintf(STDERR, " cell name is missing\n");
4762 }
4763 if (!is_an_identifier(cell)) {
4764 print_error_location("cell instantiation", mline, mfile);
4765 (void) fprintf(STDERR, " cell name <%s> is not a correct identifier\n", cell);
4767 }
4768 Num_Cells++;
4769 depth++;
4770 if (Max_Depth < depth) { /* record max depth of hierarchy */
4771 Max_Depth = depth;
4772 }
4773 if (MAXDEPTH <= depth) {
4774 mline[depth] = 0UL;
4775 print_error_location("cell instantiation", mline, mfile);
4776 (void) fprintf(STDERR, " cell hierarchy overflow, currently limited to %ld\n", MAXDEPTH);
4777 print_limits();
4779 }
4780 if (ISEMPTY(Cell_Name_Prefix[depth-1L])) {
4781 (void) strcpy(Cell_Name_Prefix[depth], cell);
4782 } else {
4783 (void) snprintf(Cell_Name_Prefix[depth], (size_t) (STRLENGTH-1L), "%s__%s", Cell_Name_Prefix[depth-1L], cell);
4784 }
4785 record_cell_nam(Cell_Name_Prefix[depth], depth, mline, mfile);
4786 str = get_token_between_braces(str, brc, tok1); /* get file name */
4787 if (ISEMPTY(tok1) || ((0 != strcmp(brc, "\"\"")) && (0 != strcmp(brc, "<>")))) {
4788 str = get_token(str, tok1, false); /* the file name as a string constant or variable */
4789 v = var_id(tok1);
4790 if ((UNDEFINED == v) || (STRING_DATA_TYPE != Var_List[v].type)) {
4791 mline[depth] = 0UL;
4792 print_error_location("cell instantiation", mline, mfile);
4793 (void) fprintf(STDERR, " cell file name is missing or not correct: <%s>\n", tok1);
4795 }
4796 str2 = Var_List[v].value;
4797 (void) get_token_between_braces(str2, brc, tok1); /* tok1 = path name of the file, a string constant */
4798 }
4799 build_pathname(brc, tok1, Net_Lib_Name, mline, mfile);
4800 simplify_pathname(tok1);
4801 (void) strcpy(inst_interface, nodnam); /* get node name part of the interface */
4802 if ((LENGTH(inst_interface) + LENGTH(str) + 1L) < LINLENGTH) {
4803 (void) strcat(inst_interface, " ");
4804 (void) strcat(inst_interface, str); /* instance interface */
4805 } else {
4806 print_error_location("cell instantiation", mline, mfile);
4807 (void) fprintf(STDERR, " interface identifiers are too long, use shorter identifiers\n");
4809 }
4810 if ((char*) NULL != strstr(inst_interface, "::")) {
4811 print_error_location("cell instantiation", mline, mfile);
4812 (void) fprintf(STDERR, " transfer by names is allowed for a data cell but not for a cell\n");
4814 }
4815 (void) strcpy(tok0, Cur_Lib_Name[depth-1L]);
4816 (void) strcpy(Cur_Lib_Name[depth], tok0);
4817 extract_directory(Cur_Lib_Name[depth], tok1, depth); /* current file follows NAPA file system */
4818 (void) snprintf(Cur_Fil_Name[depth], (size_t) (STRLENGTH-1L), "%s%s", Cur_Lib_Name[depth], tok1);
4819 if ((char*) NULL == strstr(Cur_Fil_Name[depth], ".")) { /* complete filnam with net ext. */
4820 (void) strcat(Cur_Fil_Name[depth], ".net");
4821 }
4822 record_file_nam(depth, mline, mfile);
4823 (void) time(&time_start);
4824 do { /* wait for closing of file produced by generator */
4825 fhandle[depth] = fopen(Cur_Fil_Name[depth], "r"); /* open cell file here */
4826 (void) time(&time_stop);
4827 } while (((FILE*) NULL == fhandle[depth]) && (3L >= ((long) (time_stop-time_start))));
4828 if (Expand_Flag) {
4829 (void) fprintf(STDERR, "Expanding %s\n", Cur_Fil_Name[depth]);
4830 Hierarchy_Flag = true;
4831 }
4832 if ((FILE*) NULL == fhandle[depth]) {
4833 mline[depth] = 0UL;
4834 (void) fprintf(STDERR, "\n");
4835 print_error_location("cell instantiation", mline, mfile);
4836 (void) fprintf(STDERR, " OUCH!- can't read cell file <\"%s\">\n", Cur_Fil_Name[depth]);
4838 }
4839 if ((char*) NULL == get_a_line(buff, &nl, fhandle[depth], mline, mfile)) {
4840 mline[depth] = 0UL;
4841 (void) fprintf(STDERR, "\n");
4842 print_error_location("cell instantiation", mline, mfile);
4843 (void) fprintf(STDERR, " cell file <\"%s\"> is empty\n", Cur_Fil_Name[depth]);
4845 }
4846 mline[depth] = nl; /* line numbering in cell file */
4847 str = buff;
4848 if (ISEMPTY(str)) {
4849 print_error_location("cell interface", mline, mfile);
4850 (void) fprintf(STDERR, " first line of cell file <\"%s\"> cannot be blank\n", tok1);
4852 }
4853 str = get_token(str, tok2, false); /* get interface keyword on 1st line */
4854 if (0 == strcmp(tok2, "data_interface")) {
4855 print_error_location("cell interface", mline, mfile);
4856 (void) fprintf(STDERR, " data cell file <\"%s\"> cannot be used as a cell file\n", tok1);
4858 }
4859 if (0 != strcmp(tok2, "cell_interface")) {
4860 print_error_location("cell interface", mline, mfile);
4861 (void) fprintf(STDERR, "file <\"%s\"> is not a cell as proper interface is missing on first line\n", tok1);
4863 }
4864 (void) strcpy(cell_interface, str); /* get cell_interface */
4865 str = inst_interface; /* instantiation parameters */
4866 i = 0L;
4867 for (;;) { /* store instantiation parms of cell */
4868 str = get_token(str, Inst_Plist[depth][i], true); /* keep double quotes */
4869 if ((0 == strcmp(Inst_Plist[depth][i], "&delayed" ))
4870 || (0 == strcmp(Inst_Plist[depth][i], "&constant"))
4871 || (0 == strcmp(Inst_Plist[depth][i], "&update" ))
4872 || (0 == strcmp(Inst_Plist[depth][i], "&export" ))) {
4873 print_error_location("cell instantiation", mline, mfile);
4874 (void) fprintf(STDERR, " <%s>, a short form cannot be used in a cell instantiation\n", Inst_Plist[depth][i]);
4876 }
4877 if (0 == strcmp(Inst_Plist[depth][i], "void")) { /* special care to "void" identifier */
4878 (void) snprintf(Inst_Plist[depth][i], (size_t) (LINLENGTH-1L), "_void%ld", Num_Voids);
4879 Num_Voids++;
4880 }
4881 if (0 == strcmp(Inst_Plist[depth][i], "+")) {
4882 str = get_token(str, Inst_Plist[depth][i], false);
4883 } else if (0 == strcmp(Inst_Plist[depth][i], "-")) {
4884 str = get_token(str, tok2, false);
4885 if ((LENGTH(Inst_Plist[depth][i]) + LENGTH(tok2)) < LINLENGTH) {
4886 (void) strcat(Inst_Plist[depth][i], tok2);
4887 } else {
4888 mline[depth] = 0UL;
4889 print_error_location("cell instantiation", mline, mfile);
4890 (void) fprintf(STDERR, " string overflow, parameter names are too long, use shorter identifiers\n");
4891 print_limits();
4893 }
4894 }
4895 if (ISEMPTY(Inst_Plist[depth][i])) {
4896 break;
4897 }
4898 if ((0 != strcmp(Inst_Plist[depth][i], "&delayed")) /* the only short form accepted in this interface */
4899 && (!is_an_extended_identifier(Inst_Plist[depth][i])) /* accepting extended identifier */
4900 && (UNKNOWN_TYPE == constant_type(Inst_Plist[depth][i]))) { /* constant is accepted */
4901 mline[depth] = 0UL;
4902 print_error_location("cell instantiation", mline, mfile);
4903 (void) fprintf(STDERR, " <%s> is not a correct cell parameter\n", Inst_Plist[depth][i]);
4905 }
4906 i++;
4907 if (MAXPARMS <= i) {
4908 mline[depth] = 0UL;
4909 print_error_location("cell instantiation", mline, mfile);
4910 (void) fprintf(STDERR, " overflow, too many parameters (max %ld) for cell <%s>\n", MAXPARMS, cell);
4911 print_limits();
4913 }
4914 }
4915 str = cell_interface;
4916 j = 0L;
4917 for (;;) { /* store definition parms of cell */
4918 str = get_token(str, Cell_Plist[depth][j], false); /* drop double quotes */
4919 if ((0 == strcmp(Cell_Plist[depth][j], "+")) || (0 == strcmp(Cell_Plist[depth][j], "-"))) {
4920 print_error_location("cell interface", mline, mfile);
4921 (void) fprintf(STDERR, " formal parameter cannot be signed\n");
4922 str = get_token(str, Cell_Plist[depth][j], false);
4923 /* parsing of instruction may continue */
4924 }
4925 if (ISEMPTY(Cell_Plist[depth][j])) {
4926 break;
4927 }
4928 if ('$' != (Cell_Plist[depth][j])[0]) {
4929 print_error_location("cell interface", mline, mfile);
4930 (void) fprintf(STDERR, " formal parameter <%s> must begin with letter '$'\n", Cell_Plist[depth][j]);
4932 }
4933 if (MAXPARMS <= j) {
4934 print_error_location("cell interface", mline, mfile);
4935 (void) fprintf(STDERR, " overflow, too many formal parameters (max %ld) for cell <%s>\n", MAXPARMS, cell);
4936 print_limits();
4938 }
4939 j++;
4940 }
4941 if (i != j) {
4942 mline[depth] = 0UL;
4943 print_error_location("cell instantiation", mline, mfile);
4944 (void) fprintf(STDERR, " cell file pathname: \"%s\", instance identifier: '%s'\n", Cur_Fil_Name[depth], cell);
4945 (void) fprintf(STDERR, " discrepancy between the number of formal and actual parameters\n");
4946 str1 = cell_interface;
4947 str2 = inst_interface;
4948 for (;;) {
4949 (void) strcpy(sgn1, " ");
4950 if (ISNOTEMPTY(str1)) {
4951 str1 = get_token(str1, tok1, true);
4952 if ((((0 == strcmp(tok1, "+")) || (0 == strcmp(tok1, "-"))) && ISNOTEMPTY(str1))) {
4953 (void) strcpy(sgn1, tok1);
4954 str1 = get_token(str1, tok1, true);
4955 }
4956 } else {
4957 (void) strcpy(tok1, "?");
4958 }
4959 (void) strcpy(sgn2, " ");
4960 if (ISNOTEMPTY(str2)) {
4961 str2 = get_token(str2, tok2, true);
4962 if ((((0 == strcmp(tok2, "+")) || (0 == strcmp(tok2, "-"))) && ISNOTEMPTY(str2))) {
4963 (void) strcpy(sgn2, tok2);
4964 str2 = get_token(str2, tok2, true);
4965 }
4966 } else {
4967 (void) strcpy(tok2, "?");
4968 }
4969 if ((0 == strcmp(tok1, "?")) && (0 == strcmp(tok2, "?"))) {
4970 break;
4971 }
4972 (void) fprintf(STDERR, " %s%-10s <-> %s%-10s\n", sgn1, tok1, sgn2, tok2);
4973 }
4974 (void) fprintf(STDERR, "\n");
4976 }
4977 Cell_Num_Parms[depth] = i;
4978 data_flag[depth] = false;
4979 *pseudo = UNKNOWN_KIND;
4980 return;
4981}
int is_an_extended_identifier(const char *tok)
Definition tk.c:1348

References build_pathname(), Cell_Name_Prefix, Cell_Num_Parms, Cell_Plist, constant_type(), Cur_Fil_Name, Cur_Lib_Name, Expand_Flag, extract_directory(), f1flush(), get_a_line(), get_token(), get_token_between_braces(), Hierarchy_Flag, Inst_Plist, is_an_extended_identifier(), is_an_identifier(), ISEMPTY, ISNOTEMPTY, LENGTH, LINLENGTH, Max_Depth, MAXDEPTH, MAXPARMS, Net_Lib_Name, Num_Cells, Num_Voids, print_error_banner_and_exit(), print_error_location(), print_limits(), record_cell_nam(), record_file_nam(), simplify_pathname(), STDERR, STRING_DATA_TYPE, STRLENGTH, UNDEFINED, UNKNOWN_KIND, UNKNOWN_TYPE, var_id(), and Var_List.

Referenced by line_parsing().

◆ process_gen()

char * process_gen ( char * str,
long * pseudo,
char * cell )

Definition at line 4560 of file lp.c.

4560 {
4561
4562 /* PSEUDO NODE GENERATOR PROCESSING */
4563 /* Called after the processing of instruction "node". */
4564 /* Executes a system call to trigger cell generation. */
4565 /* Call the pseudo-node post processing of a "cell" */
4566
4567 char command0[LINLENGTH] = {'\0'};
4568 char command1[LINLENGTH] = {'\0'};
4569 char command2[LINLENGTH] = {'\0'};
4570 char tok1[LINLENGTH] = {'\0'};
4571 static char tok2[LINLENGTH] = {'\0'}; /* static ! <<<< pointed by process_cell() */
4572 char tok3[LINLENGTH] = {'\0'};
4573 char tok4[LINLENGTH] = {'\0'};
4574 char tok5[LINLENGTH] = {'\0'};
4575 char brc[3] = {'\0'};
4576 char *s = (char*) NULL;
4577 char *t = (char*) NULL;
4578 long status;
4579#if (IS_WIN64 == PLATFORM) /* case-insensitive OS */
4580 long i;
4581#endif
4582 long v;
4583 long o;
4584 FILE *fp = (FILE*) NULL;
4585 time_t time_start;
4586 time_t time_stop;
4587
4588 /* (width declaration is trapped when invoking cell after generator) */
4589
4590 if (data_flag[depth]) {
4591 print_error_location("data", mline, mfile);
4592 (void) fprintf(STDERR, " generator calls are not allowed in a data cell file\n");
4594 }
4595 str = get_token(str, cell, true); /* get cell instantiation name */
4596 str = get_token_between_braces(str, brc, tok3); /* process following NAPA file system */
4597 build_pathname(brc, tok3, Generator_Lib_Name, mline, mfile);
4598 (void) strcpy(tok4, Cur_Lib_Name[depth]); /* do not modify Cur_Lib_Name[] */
4599 extract_directory(tok4, tok3, depth);
4600 (void) snprintf(tok1, (size_t) (LINLENGTH-1L), "%s%s", tok4, tok3); /* there is no record of new path */
4601 if (('/' == tok1[0]) || (':' == tok1[1])) {
4602 (void) strcpy(tok3, tok1);
4603 } else {
4604 (void) snprintf(tok3, (size_t) (LINLENGTH-1L), "%s%s", Cur_Lib_Name[depth-1L], tok1);
4605 if (LENGTH(tok3) >= LINLENGTH) {
4606 print_error_location("hierarchy", mline, mfile);
4607 (void) fprintf(STDERR, " string buffer overflow while tracking generator file pathname\n");
4608 print_limits();
4610 }
4611 simplify_pathname(tok1);
4612 }
4613 v = var_id(tok3);
4614 if ((UNDEFINED != v) && (STRING_DATA_TYPE == Var_List[v].type)) {
4615 (void) strcpy(tok3, Var_List[v].value);
4616 }
4617#if (IS_WIN64 == PLATFORM) /* Unix slash and DOS backslash */
4618 i = 0L;
4619 while ('\0' != tok3[i]) {
4620 if ('/' == tok3[i]) {
4621 tok3[i] = '\\';
4622 }
4623 i++;
4624 }
4625#endif /* tok3 contains the executable call */
4626 (void) snprintf(tok1, (size_t) (LINLENGTH-1L), "%s%s_%ld", Cur_Lib_Name[0], cell, Num_Generators);
4627 (void) snprintf(tok2, (size_t) (LINLENGTH-1L), "%s \"%s.gen\" %s", cell, tok1, str); /* for cell proc. */
4628 (void) snprintf(command0, (size_t) (LINLENGTH-1L), "%s %s.gen", tok3, tok1); /* build system command */
4629 (void) snprintf(tok4, (size_t) (LINLENGTH-1L), "%s.gen", tok1); /* build cell file name */
4630 (void) time(&time_start);
4631 simplify_pathname(tok4);
4632 do { /* may wait for the opening of file */
4633 fp = fopen(tok4, "w"); /* clear content if cell file exists */
4634 (void) time(&time_stop);
4635 } while (((FILE*) NULL == fp) && (3L >= ((long) (time_stop-time_start))));
4636 if ((FILE*) NULL == fp) {
4637 print_error_location("generator", mline, mfile);
4638 (void) fprintf(STDERR, " OUCH!- can't create cell file <%s>\n\n", tok4);
4640 }
4641 (void) time(&time_start);
4642 do { /* may wait for the closing of file */
4643 o = fclose(fp);
4644 (void) time(&time_stop);
4645 } while ((EOF == o) && (3L >= ((long) (time_stop-time_start))));
4646 if (EOF == o) {
4647 print_error_location("generator", mline, mfile);
4648 (void) fprintf(STDERR, " OUCH!- cell file pathname <%s> is locked\n", tok4);
4650 }
4651 resolve_pathnames(str, depth); /* resolve pathname using conventions */
4652 simplify_pathname(str);
4653 for (;;) {
4654 (void) strcpy(tok5, str);
4655 str = get_token_between_braces(str, brc, tok3);
4656 if (0 == strcmp(brc, "<>")) {
4657 print_error_location("generator", mline, mfile);
4658 (void) fprintf(STDERR, "<%s>: triangular brackets are not expected here\n", tok3);
4660 }
4661 (void) strcpy(str, tok5);
4662 str = get_token(str, tok3, false); /* no quote in command line */
4663 if (ISEMPTY(tok3)) {
4664 break;
4665 }
4666 v = var_id(tok3);
4667 if ((UNDEFINED != v) && (STRING_DATA_TYPE == Var_List[v].type)) {
4668 (void) strcpy(tok3, Var_List[v].value);
4669 Var_List[v].used = true;
4670 }
4671 if ((LENGTH(command0) + LENGTH(tok3) + 1L) < LINLENGTH) {
4672 (void) strcat(command0, " ");
4673 (void) strcat(command0, tok3);
4674 } else {
4675 print_error_location("generator", mline, mfile);
4676 (void) fprintf(STDERR, " string overflow, parameter names are too long, use shorter identifiers\n");
4677 print_limits();
4679 }
4680 }
4681 s = command0;
4682 (void) compact_line(s, command1); /* compact line */
4683 (void) strcpy(command2, command1); /* shorter text to print on stderr */
4684 if (98L < LENGTH(command2)) {
4685 s = &(command2[90L]);
4686 t = &(command2[LENGTH(command2) - 8L]);
4687 while ((' ' != *s) && (s != t)) {
4688 s++;
4689 }
4690 *(s++) = ' '; *(s++) = ' '; /* " ... etc. " at the end of shortened command */
4691 *(s++) = '.'; *(s++) = '.'; *(s++) = '.'; *(s++) = ' ';
4692 *(s++) = 'e'; *(s++) = 't'; *(s++) = 'c'; *(s++) = '.';
4693 *(s++) = ' '; *(s++) = '\0';
4694 }
4695 if (Expand_Flag) {
4696 (void) fprintf(STDERR, "Generating and ");
4697 } else {
4698 (void) fprintf(STDERR, "\nNAPA Compiler Information: (generator)\n");
4699 (void) fprintf(STDERR, " Generating cell file <./%s>,\n", tok4);
4700 (void) fprintf(STDERR, " through system call: '%s'\n", command2);
4701 }
4702
4703 (void) f1flush((FILE*) NULL); /* just in case of problem, who knows? */
4704
4705 status = system(command1);
4706
4707 (void) f1flush((FILE*) NULL); /* just in case of problem, who knows? */
4708
4709 if (0L != status) {
4710 (void) fprintf(STDERR, "\n");
4711 print_error_location("generator", mline, mfile);
4712 (void) fprintf(STDERR, " generation of the cell file <%s> didn't succeed!\n\n", tok4);
4714 }
4715 if (!Expand_Flag) {
4716 (void) fprintf(STDERR, "\n");
4717 }
4718 *pseudo = UNKNOWN_KIND;
4719 increment_generator_number("generator");
4720 return tok2;
4721}
void increment_generator_number(const char *kind)
Definition id.c:320
EXTERN char * Generator_Lib_Name
Definition napa.h:913
EXTERN long Num_Generators
Definition napa.h:816
char * compact_line(char *str1, char *str2)
Definition tk.c:1468

References build_pathname(), compact_line(), Cur_Lib_Name, Expand_Flag, extract_directory(), f1flush(), Generator_Lib_Name, get_token(), get_token_between_braces(), increment_generator_number(), ISEMPTY, LENGTH, LINLENGTH, Num_Generators, print_error_banner_and_exit(), print_error_location(), print_limits(), resolve_pathnames(), simplify_pathname(), STDERR, STRING_DATA_TYPE, UNDEFINED, UNKNOWN_KIND, var_id(), and Var_List.

Referenced by line_parsing().

◆ process_width()

long process_width ( const char * brc,
const char * tok,
const char * instr )

Definition at line 4986 of file lp.c.

4986 {
4987 long w;
4988 long wmax;
4989 long signed_number;
4990 if ((0 != strcmp(brc, "()")) && (0 != strcmp(brc, "<>"))) {
4991 return 0L; /* width null: 'unlimited' width */
4992 }
4993 signed_number = ( 0 == strcmp(brc, "()") ) ? true : false;
4994 if (1 != sscanf(tok, "%li", &w)) {
4995 print_error_location(instr, mline, mfile);
4996 (void) fprintf(STDERR, " width casting %c%s%c must be a positive integer constant\n", brc[0], tok, brc[1]);
4997 w = 0L;
4998 return 0L;
4999 }
5000 wmax = 8L * ((long) sizeof(NAPA_DIGITAL_TYPE)); /* number of bits of NAPA_DIGITAL_TYPE */
5001 if ((w == wmax) && (signed_number)) {
5002 return 0L; /* if width max, no special process */
5003 }
5004 if (((1L > w) || (w > wmax)) && (signed_number)) { /* signed numbers width casting */
5005 print_error_location(instr, mline, mfile);
5006 (void) fprintf(STDERR, " width casting %c%ld%c is outside range [1..%ld] of signed digital signals\n", brc[0], w, brc[1], wmax);
5007 w = 0L;
5008 return 0L;
5009 }
5010 if (((1L > w) || (w >= wmax)) && (!signed_number)) { /* unsigned numbers width casting */
5011 print_error_location(instr, mline, mfile);
5012 (void) fprintf(STDERR, " width casting %c%ld%c is outside range [1..%ld[ of unsigned digital signals\n", brc[0], w, brc[1], wmax);
5013 w = 0L;
5014 return 0L;
5015 }
5016 if (!signed_number) { /* width neg: unsigned long rolloff */
5017 return -w; /* width pos: signed long rolloff */
5018 }
5019 return w;
5020}
#define NAPA_DIGITAL_TYPE
Definition napa.h:129

References NAPA_DIGITAL_TYPE, print_error_location(), and STDERR.

Referenced by line_parsing().

◆ read_doub_format()

void read_doub_format ( char * str)

Definition at line 3959 of file lp.c.

3959 {
3960
3961 char tok1[STRLENGTH] = {'\0'};
3962 char brc[3] = {'\0'};
3963
3964 if (0 == strncmp(str, "S", 1)) {
3965 (void) snprintf(str, (size_t) (STRLENGTH-1L), "\"%s\"", R_FORMAT_S);
3966 }
3967 if (0 == strncmp(str, "M", 1)) {
3968 (void) snprintf(str, (size_t) (STRLENGTH-1L), "\"%s\"", R_FORMAT_M);
3969 }
3970 if (0 == strncmp(str, "L", 1)) {
3971 (void) snprintf(str, (size_t) (STRLENGTH-1L), "\"%s\"", R_FORMAT_L);
3972 }
3973 str = get_token_between_braces(str, brc, tok1);
3974 if (0 != strcmp(brc, "\"\"")) {
3975 print_error_location("format", mline, mfile);
3976 (void) fprintf(STDERR, " double quotes are missing\n");
3977 return;
3978 }
3979 if (ISEMPTY(tok1)) {
3980 print_error_location("format", mline, mfile);
3981 (void) fprintf(STDERR, " analog number format specification is invalid\n");
3982 return;
3983 }
3984 if (ISNOTEMPTY(str)) {
3985 print_error_location("format", mline, mfile);
3986 (void) fprintf(STDERR, " spurious text appears at the end of format definition: <%s>\n", str);
3987 }
3988 if ((0 != strcmp(R_Format, tok1)) && (0 != strcmp(R_Format, DEFAULT_R_FORMAT))) {
3989 print_warning_location("format", mline, mfile);
3990 (void) fprintf(STDERR, " redefining analog number output format\n");
3991 }
3992 (void) strcpy(R_Format, tok1);
3993 (void) snprintf(tok1, (size_t) (STRLENGTH-1L), R_Format, (double) 1.0);
3994 (void) snprintf(R_String_Format, (size_t) (STRLENGTH-1L), "%%%lds", LENGTH(tok1)-1L); /* eff. string length of this format */
3995 return;
3996}
EXTERN char R_Format[2047L]
Definition napa.h:897
EXTERN char R_String_Format[2047L]
Definition napa.h:903
#define R_FORMAT_L
Definition napa.h:164
#define DEFAULT_R_FORMAT
Definition napa.h:175
#define R_FORMAT_S
Definition napa.h:162
#define R_FORMAT_M
Definition napa.h:163

References DEFAULT_R_FORMAT, get_token_between_braces(), ISEMPTY, ISNOTEMPTY, LENGTH, print_error_location(), print_warning_location(), R_Format, R_FORMAT_L, R_FORMAT_M, R_FORMAT_S, R_String_Format, STDERR, and STRLENGTH.

Referenced by get_format().

◆ read_hex_format()

void read_hex_format ( char * str)

Definition at line 4039 of file lp.c.

4039 {
4040
4041 char tok1[STRLENGTH] = {'\0'};
4042 char brc[3] = {'\0'};
4043
4044 if (0 == strncmp(str, "S", 1)) {
4045 (void) snprintf(str, (size_t) (STRLENGTH-1L), "\"%s\"", X_FORMAT_S);
4046 }
4047 if (0 == strncmp(str, "M", 1)) {
4048 (void) snprintf(str, (size_t) (STRLENGTH-1L), "\"%s\"", X_FORMAT_M);
4049 }
4050 if (0 == strncmp(str, "L", 1)) {
4051 (void) snprintf(str, (size_t) (STRLENGTH-1L), "\"%s\"", X_FORMAT_L);
4052 }
4053 str = get_token_between_braces(str, brc, tok1);
4054 if (0 != strcmp(brc, "\"\"")) {
4055 print_error_location("format", mline, mfile);
4056 (void) fprintf(STDERR, " double quotes are missing\n");
4057 return;
4058 }
4059 if (ISEMPTY(tok1)) {
4060 print_error_location("format", mline, mfile);
4061 (void) fprintf(STDERR, " digital hexadecimal number format specification is invalid\n");
4062 return;
4063 }
4064 if (ISNOTEMPTY(str)) {
4065 print_error_location("format", mline, mfile);
4066 (void) fprintf(STDERR, " spurious text appears at the end of format definition: <%s>\n", str);
4067 }
4068 if ((0 != strcmp(X_Format, tok1)) && (0 != strcmp(X_Format, DEFAULT_X_FORMAT))) {
4069 print_warning_location("format", mline, mfile);
4070 (void) fprintf(STDERR, " redefining digital hexadecimal number output format\n");
4071 }
4072 (void) strcpy(X_Format, tok1);
4073 (void) snprintf(tok1, (size_t) (STRLENGTH-1L), X_Format, (NAPA_DIGITAL_TYPE) 1LL);
4074 (void) snprintf(X_String_Format, (size_t) (STRLENGTH-1L), "%%%lds", LENGTH(tok1)-1L); /* eff string length of this format */
4075 return;
4076}
#define X_FORMAT_M
Definition napa.h:158
#define X_FORMAT_S
Definition napa.h:157
EXTERN char X_String_Format[2047L]
Definition napa.h:905
EXTERN char X_Format[2047L]
Definition napa.h:900
#define X_FORMAT_L
Definition napa.h:159
#define DEFAULT_X_FORMAT
Definition napa.h:174

References DEFAULT_X_FORMAT, get_token_between_braces(), ISEMPTY, ISNOTEMPTY, LENGTH, NAPA_DIGITAL_TYPE, print_error_location(), print_warning_location(), STDERR, STRLENGTH, X_Format, X_FORMAT_L, X_FORMAT_M, X_FORMAT_S, and X_String_Format.

Referenced by get_format().

◆ read_int_format()

void read_int_format ( char * str)

Definition at line 3999 of file lp.c.

3999 {
4000
4001 char tok1[STRLENGTH] = {'\0'};
4002 char brc[3] = {'\0'};
4003
4004 if (0 == strncmp(str, "S", 1)) {
4005 (void) snprintf(str, (size_t) (STRLENGTH-1L), "\"%s\"", I_FORMAT_S);
4006 }
4007 if (0 == strncmp(str, "M", 1)) {
4008 (void) snprintf(str, (size_t) (STRLENGTH-1L), "\"%s\"", I_FORMAT_M);
4009 }
4010 if (0 == strncmp(str, "L", 1)) {
4011 (void) snprintf(str, (size_t) (STRLENGTH-1L), "\"%s\"", I_FORMAT_L);
4012 }
4013 str = get_token_between_braces(str, brc, tok1);
4014 if (0 != strcmp(brc, "\"\"")) {
4015 print_error_location("format", mline, mfile);
4016 (void) fprintf(STDERR, " double quotes are missing\n");
4017 return;
4018 }
4019 if (ISEMPTY(tok1)) {
4020 print_error_location("format", mline, mfile);
4021 (void) fprintf(STDERR, " digital number format specification is invalid\n");
4022 return;
4023 }
4024 if (ISNOTEMPTY(str)) {
4025 print_error_location("format", mline, mfile);
4026 (void) fprintf(STDERR, " spurious text appears at the end of format definition: <%s>\n", str);
4027 }
4028 if ((0 != strcmp(I_Format, tok1)) && (0 != strcmp(I_Format, DEFAULT_I_FORMAT))) {
4029 print_warning_location("format", mline, mfile);
4030 (void) fprintf(STDERR, " redefining digital number output format\n");
4031 }
4032 (void) strcpy(I_Format, tok1);
4033 (void) snprintf(tok1, (size_t) (STRLENGTH-1L), I_Format, (NAPA_DIGITAL_TYPE) 1LL);
4034 (void) snprintf(I_String_Format, (size_t) (STRLENGTH-1L), "%%%lds", LENGTH(tok1)-1L); /* eff string length of this format */
4035 return;
4036}
EXTERN char I_String_Format[2047L]
Definition napa.h:902
#define I_FORMAT_S
Definition napa.h:152
EXTERN char I_Format[2047L]
Definition napa.h:896
#define I_FORMAT_M
Definition napa.h:153
#define I_FORMAT_L
Definition napa.h:154
#define DEFAULT_I_FORMAT
Definition napa.h:173

References DEFAULT_I_FORMAT, get_token_between_braces(), I_Format, I_FORMAT_L, I_FORMAT_M, I_FORMAT_S, I_String_Format, ISEMPTY, ISNOTEMPTY, LENGTH, NAPA_DIGITAL_TYPE, print_error_location(), print_warning_location(), STDERR, and STRLENGTH.

Referenced by get_format().

◆ read_str_format()

void read_str_format ( char * str)

Definition at line 4079 of file lp.c.

4079 {
4080
4081 char tok1[STRLENGTH] = {'\0'};
4082 char brc[3] = {'\0'};
4083
4084 if (0 == strncmp(str, "S", 1)) {
4085 (void) snprintf(str, (size_t) (STRLENGTH-1L), "\"%s\"", S_FORMAT_S);
4086 }
4087 if (0 == strncmp(str, "M", 1)) {
4088 (void) snprintf(str, (size_t) (STRLENGTH-1L), "\"%s\"", S_FORMAT_M);
4089 }
4090 if (0 == strncmp(str, "L", 1)) {
4091 (void) snprintf(str, (size_t) (STRLENGTH-1L), "\"%s\"", S_FORMAT_L);
4092 }
4093 str = get_token_between_braces(str, brc, tok1);
4094 if (0 != strcmp(brc, "\"\"")) {
4095 print_error_location("format", mline, mfile);
4096 (void) fprintf(STDERR, " double quotes are missing\n");
4097 return;
4098 }
4099 if (ISEMPTY(tok1)) {
4100 print_error_location("format", mline, mfile);
4101 (void) fprintf(STDERR, " string format specification is invalid\n");
4102 return;
4103 }
4104 if (ISNOTEMPTY(str)) {
4105 print_error_location("format", mline, mfile);
4106 (void) fprintf(STDERR, " spurious text appears at the end of format definition: <%s>\n", str);
4107 }
4108 if ((0 != strcmp(S_Format, tok1)) && (0 != strcmp(S_Format, DEFAULT_S_FORMAT))) {
4109 print_warning_location("format", mline, mfile);
4110 (void) fprintf(STDERR, " redefining string output format\n");
4111 }
4112 (void) strcpy(S_Format, tok1);
4113 (void) snprintf(tok1, (size_t) (STRLENGTH-1L), S_Format, " ");
4114 (void) snprintf(S_String_Format, (size_t) (STRLENGTH-1L), "%%%lds", LENGTH(tok1)-1L); /* eff. string length resulting of format */
4115 return;
4116}
#define S_FORMAT_S
Definition napa.h:167
EXTERN char S_Format[2047L]
Definition napa.h:898
EXTERN char S_String_Format[2047L]
Definition napa.h:904
#define DEFAULT_S_FORMAT
Definition napa.h:176
#define S_FORMAT_L
Definition napa.h:169
#define S_FORMAT_M
Definition napa.h:168

References DEFAULT_S_FORMAT, get_token_between_braces(), ISEMPTY, ISNOTEMPTY, LENGTH, print_error_location(), print_warning_location(), S_Format, S_FORMAT_L, S_FORMAT_M, S_FORMAT_S, S_String_Format, STDERR, and STRLENGTH.

Referenced by get_format().

◆ rearrange_data_interfaces()

void rearrange_data_interfaces ( char * data_if,
char * inst_if,
const unsigned long * mlin,
const unsigned long * mfil )

Definition at line 5025 of file lp.c.

5025 {
5026 char *strd = (char*) NULL;
5027 char *stri = (char*) NULL;
5028 char *t1 = (char*) NULL;
5029 char *t2 = (char*) NULL;
5030 char tokd[STRLENGTH] = {'\0'};
5031 char toki[STRLENGTH] = {'\0'};
5032 char tok1[STRLENGTH] = {'\0'};
5033 char tok2[STRLENGTH] = {'\0'};
5034 char ilist1[MAXPARMS][STRLENGTH];
5035 char ilist2[MAXPARMS][STRLENGTH];
5036 char dlist2[MAXPARMS][STRLENGTH];
5037 char dlist3[MAXPARMS][STRLENGTH];
5038 char dlist4[MAXPARMS][STRLENGTH];
5039 long i, d, j, dd, ni, nd;
5040 int flagd[MAXPARMS];
5041
5042 if ((char*) NULL == strstr(inst_if, "::")) { /* pure transfer by position, no process here */
5043 return;
5044 }
5045 /* as it is not a transfer per position, we have first to check the syntax and if all the parameters are transferred per name */
5046 if (((char*) NULL != strstr(inst_if, " ::")) || ((char*) NULL != strstr(inst_if, ":: "))) {
5047 print_error_location("data", mlin, mfil);
5048 (void) fprintf(STDERR, " syntax error, no space is allowed before or after the operator '::'\n");
5050 }
5051 stri = inst_if;
5052 ni = 0L;
5053 for (;;) {
5054 stri = get_token(stri, toki, false);
5055 if (ISEMPTY(toki)) {
5056 break;
5057 }
5058 (void) strcpy(tok1, toki);
5059 (void) strcpy(tok2, toki);
5060 t1 = strstr(tok1, "::");
5061 t2 = strstr(tok2, "::");
5062 if ((char*) NULL != t1) {
5063 (void) strcpy(tok1, t1+2); /* passing parameters by name */
5064 clean_line(tok1);
5065 *t2 = '\0';
5066 (void) strcpy(ilist1[ni], tok1);
5067 (void) strcpy(ilist2[ni], tok2);
5068 } else { /* passing parameters by position */
5069 print_error_location("data", mlin, mfil);
5070 (void) fprintf(STDERR, " inconsistent transfer of parameters, by name or by position?\n");
5072 }
5073 ni++;
5074 }
5075 /* syntax is ok and the transfer of the parameters per name is consistent */
5076 strd = data_if;
5077 nd = 0L;
5078 for (;;) {
5079 strd = get_token(strd, tokd, false);
5080 if (ISEMPTY(tokd)) {
5081 break;
5082 }
5083 t2 = tokd + 1;
5084 (void) strcpy(dlist2[nd], t2);
5085 nd++;
5086 }
5087 /* the number of parameters are not abnormal */
5088 for (d = 0L; d < nd; d++) {
5089 flagd[d] = false;
5090 }
5091 for (d = 0L; d < nd; d++) {
5092 for (i = 0L; i < ni; i++) {
5093 if (0 == strcmp(ilist2[i], dlist2[d])) {
5094 flagd[d] = true;
5095 }
5096 }
5097 }
5098 dd = 0L;
5099 for (d = 0L; d < nd; d++) {
5100 if (flagd[d]) {
5101 (void) strcpy(dlist3[dd], dlist2[d]);
5102 dd++;
5103 }
5104 }
5105 nd = dd;
5106 /* the parameters of the data cell are now pruned but not sorted */
5107 dd = 0L;
5108 for (i = 0L; i < ni; i++) {
5109 for (d = 0L; d < nd; d++) {
5110 if (0 == strcmp(ilist2[i], dlist3[d])) {
5111 (void) strcpy(dlist4[dd], dlist3[d] );
5112 dd++;
5113 }
5114 }
5115 }
5116 /* the pruned parameters of the data cell are now sorted */
5117 if (nd != ni) {
5118 print_error_location("data", mlin, mfil);
5119 if ((ni - nd) == 1L) {
5120 (void) fprintf(stderr, " 1 parameter of the instantiation cannot be matched with the data cell:\n");
5121 } else {
5122 (void) fprintf(stderr, "%ld parameters of the instantiation cannot be matched with the data cell:\n", ni-nd);
5123 }
5124 fprintf(stderr, "\n%20s %15s\n", "instantiation", "data cell");
5125 i = 0LL;
5126 d = 0LL;
5127 for (j = 0L; j < MAX(ni, nd); j++) {
5128 if (0 == strcmp(ilist2[i], dlist4[d])) {
5129 fprintf(stderr, "%20s %15s\n", ilist1[i], dlist4[d]);
5130 i++;
5131 d++;
5132 } else {
5133 fprintf(stderr, "%20s %15s %15s", ilist1[i], "...", "<<< ???\n");
5134 i++;
5135 }
5136 }
5138 }
5139 /* update the interfaces */
5140 (void) strcpy(inst_if, "");
5141 for (i = 0L; i < ni; i++) {
5142 (void) strcat(inst_if, ilist1[i]);
5143 (void) strcat(inst_if, " ");
5144 }
5145 (void) strcpy(data_if, "");
5146 for (d = 0L; d < nd; d++) {
5147 (void) strcat(data_if, "$");
5148 (void) strcat(data_if, dlist4[d]);
5149 (void) strcat(data_if, " ");
5150 }
5151 return;
5152}
void clean_line(char *str)
Definition tk.c:1397

References clean_line(), get_token(), ISEMPTY, MAX, MAXPARMS, print_error_banner_and_exit(), print_error_location(), STDERR, and STRLENGTH.

Referenced by get_data().

◆ record_cell_nam()

void record_cell_nam ( const char * nam,
long cur_depth,
unsigned long * mlin,
const unsigned long * mfil )

Definition at line 5158 of file lp.c.

5158 {
5159 char *s = (char*) NULL;
5160 long i;
5161 for (i = 0L; i < Num_Instances; i++) {
5163 if (0 == strcmp(nam, s)) {
5164 mlin[cur_depth] = 0UL;
5165 print_error_location("cell instantiation", mlin, mfil);
5166 (void) fprintf(STDERR, " cell name <%s> is not unique\n", s);
5168 }
5169 }
5172 return;
5173}
void increment_instance_number(const char *kind)
Definition id.c:386
EXTERN long Num_Instances
Definition napa.h:821
EXTERN char * Record_Instantiation_Name[511L]
Definition napa.h:939

References increment_instance_number(), Num_Instances, print_error_banner_and_exit(), print_error_location(), Record_Instantiation_Name, STDERR, and strcpy_alloc().

Referenced by get_data(), and process_cell().

◆ record_file_nam()

void record_file_nam ( long d,
const unsigned long * mlin,
const unsigned long * mfil )

Definition at line 5178 of file lp.c.

5178 {
5179 long i, j;
5180 for (i = 1L; i < Num_FileCells; i++) { /* number 0 is main_list */
5181 if (0 == fnstrcmp(Cur_Fil_Name[d], Record_Cell_File_Table[i])) { /* already recorded */
5182 for (j = 1L; j < d; j++) {
5183 if (0 == fnstrcmp(Cur_Fil_Name[d], Cur_Fil_Name[j])) {
5184 print_error_location("cell instantiation", mlin, mfil);
5185 (void) fprintf(STDERR, " it is forbidden to loop instantiations of cells!\n");
5187 }
5188 }
5190 mfile[d] = (unsigned long) i; /* file number of existing file */
5191 return; /* already recorded, but no loop, all is OK */
5192 }
5193 }
5195 Record_Cell_File_Usage[Num_FileCells] = 1; /* first use of this file */
5196 mfile[d] = (unsigned long) Num_FileCells;
5197 increment_filecell_number("cell file");
5198 return;
5199}
void increment_filecell_number(const char *kind)
Definition id.c:293
EXTERN char * Record_Cell_File_Table[511L]
Definition napa.h:940
EXTERN long Num_FileCells
Definition napa.h:814
EXTERN long Record_Cell_File_Usage[511L]
Definition napa.h:941

References Cur_Fil_Name, fnstrcmp(), increment_filecell_number(), Num_FileCells, print_error_banner_and_exit(), print_error_location(), Record_Cell_File_Table, Record_Cell_File_Usage, STDERR, and strcpy_alloc().

Referenced by get_data(), line_parsing(), and process_cell().

◆ trap_unconsistencies()

void trap_unconsistencies ( void )

Definition at line 5269 of file lp.c.

5269 {
5270 if ((Interpolate_Flag) && (!Periodic_Flag)) {
5271 print_error_location("sampling rate", Sampling_List.mline, Sampling_List.mfile);
5272 (void) fprintf(STDERR, " user-defined sampling rate is not compatible with interpolation concept\n");
5273 }
5274 if (((Fs_Flag) || (Ts_Flag)) && (!Periodic_Flag)) {
5275 print_error_location("sampling rate", Sampling_List.mline, Sampling_List.mfile);
5276 (void) fprintf(STDERR, " user-defined sampling rate is not compatible with a sampling period or frequency definition\n");
5277 }
5278 if ((!Terminate_Flag) && (0 == Error_Flag)) {
5279 print_error_location("simulation control", (unsigned long*) NULL, (unsigned long*) NULL);
5280 (void) fprintf(STDERR, " No explicit instruction is given to the simulator to terminate!\n" );
5281 (void) fprintf(STDERR, " One instruction <terminate> is required in a simulation netlist. \n" );
5282 }
5283 if ((0L == Num_Headers) && (0 == Error_Flag)) {
5284 print_error_location("header", (unsigned long*) NULL, (unsigned long*) NULL);
5285 (void) fprintf(STDERR, " Generic header file <napa.hdr> must be called in every simulation.\n" );
5286 (void) fprintf(STDERR, " This header contains essential informations for the compilation.\n" );
5287 (void) fprintf(STDERR, " If needed, this header can be replaced by a customized version.\n" );
5288 (void) fprintf(STDERR, " File name must begin by the prefix <napa>, the suffix must be <.hdr>\n");
5289 }
5290 if ((Ping_Flag) && (Cmdline_Flag)) {
5291 Ping_Flag = false;
5292 (void) fprintf(STDERR, "\n");
5293 print_warning_location("ping", Ping_List.mline, Ping_List.mfile);
5294 (void) fprintf(STDERR, " Instruction 'ping' is ignored in a standalone simulator\n\n");
5295 return;
5296 }
5297 return;
5298}

References Cmdline_Flag, Error_Flag, Fs_Flag, Interpolate_Flag, Num_Headers, Periodic_Flag, Ping_Flag, Ping_List, print_error_location(), print_warning_location(), Sampling_List, STDERR, Terminate_Flag, and Ts_Flag.

Referenced by line_parsing().