void test_EOC(void) { int temp; if(old_config_style){ temp = is_EOC('\n'); TEST_ASSERT_TRUE(temp); } else { temp = is_EOC(';'); TEST_ASSERT_TRUE(temp); } temp = is_EOC('A'); TEST_ASSERT_FALSE(temp); temp = is_EOC('1'); TEST_ASSERT_FALSE(temp); }
/* * yylex() - function that does the actual scanning. * Bison expects this function to be called yylex and for it to take no * input and return an int. * Conceptually yylex "returns" yylval as well as the actual return * value representing the token or type. */ int yylex(void) { static follby followedby = FOLLBY_TOKEN; size_t i; int instring; int yylval_was_set; int converted; int token; /* The return value */ int ch; instring = FALSE; yylval_was_set = FALSE; do { /* Ignore whitespace at the beginning */ while (EOF != (ch = lex_getch(lex_stack)) && isspace(ch) && !is_EOC(ch)) ; /* Null Statement */ if (EOF == ch) { if ( ! lex_pop_file()) return 0; token = T_EOC; goto normal_return; } else if (is_EOC(ch)) { /* end FOLLBY_STRINGS_TO_EOC effect */ followedby = FOLLBY_TOKEN; token = T_EOC; goto normal_return; } else if (is_special(ch) && FOLLBY_TOKEN == followedby) { /* special chars are their own token values */ token = ch; /* * '=' outside simulator configuration implies * a single string following as in: * setvar Owner = "The Boss" default */ if ('=' == ch && old_config_style) followedby = FOLLBY_STRING; yytext[0] = (char)ch; yytext[1] = '\0'; goto normal_return; } else lex_ungetch(ch, lex_stack); /* save the position of start of the token */ lex_stack->tokpos = lex_stack->curpos; /* Read in the lexeme */ i = 0; while (EOF != (ch = lex_getch(lex_stack))) { yytext[i] = (char)ch; /* Break on whitespace or a special character */ if (isspace(ch) || is_EOC(ch) || '"' == ch || (FOLLBY_TOKEN == followedby && is_special(ch))) break; /* Read the rest of the line on reading a start of comment character */ if ('#' == ch) { while (EOF != (ch = lex_getch(lex_stack)) && '\n' != ch) ; /* Null Statement */ break; } i++; if (i >= COUNTOF(yytext)) goto lex_too_long; } /* Pick up all of the string inside between " marks, to * end of line. If we make it to EOL without a * terminating " assume it for them. * * XXX - HMS: I'm not sure we want to assume the closing " */ if ('"' == ch) { instring = TRUE; while (EOF != (ch = lex_getch(lex_stack)) && ch != '"' && ch != '\n') { yytext[i++] = (char)ch; if (i >= COUNTOF(yytext)) goto lex_too_long; } /* * yytext[i] will be pushed back as not part of * this lexeme, but any closing quote should * not be pushed back, so we read another char. */ if ('"' == ch) ch = lex_getch(lex_stack); } /* Pushback the last character read that is not a part * of this lexeme. This fails silently if ch is EOF, * but then the EOF condition persists and is handled on * the next turn by the include stack mechanism. */ lex_ungetch(ch, lex_stack); yytext[i] = '\0'; } while (i == 0); /* Now return the desired token */ /* First make sure that the parser is *not* expecting a string * as the next token (based on the previous token that was * returned) and that we haven't read a string. */ if (followedby == FOLLBY_TOKEN && !instring) { token = is_keyword(yytext, &followedby); if (token) { /* * T_Server is exceptional as it forces the * following token to be a string in the * non-simulator parts of the configuration, * but in the simulator configuration section, * "server" is followed by "=" which must be * recognized as a token not a string. */ if (T_Server == token && !old_config_style) followedby = FOLLBY_TOKEN; goto normal_return; } else if (is_integer(yytext)) { yylval_was_set = TRUE; errno = 0; if ((yylval.Integer = strtol(yytext, NULL, 10)) == 0 && ((errno == EINVAL) || (errno == ERANGE))) { msyslog(LOG_ERR, "Integer cannot be represented: %s", yytext); if (lex_from_file()) { exit(1); } else { /* force end of parsing */ yylval.Integer = 0; return 0; } } token = T_Integer; goto normal_return; } else if (is_u_int(yytext)) { yylval_was_set = TRUE; if ('0' == yytext[0] && 'x' == tolower((unsigned long)yytext[1])) converted = sscanf(&yytext[2], "%x", &yylval.U_int); else converted = sscanf(yytext, "%u", &yylval.U_int); if (1 != converted) { msyslog(LOG_ERR, "U_int cannot be represented: %s", yytext); if (lex_from_file()) { exit(1); } else { /* force end of parsing */ yylval.Integer = 0; return 0; } } token = T_U_int; goto normal_return; } else if (is_double(yytext)) { yylval_was_set = TRUE; errno = 0; if ((yylval.Double = atof(yytext)) == 0 && errno == ERANGE) { msyslog(LOG_ERR, "Double too large to represent: %s", yytext); exit(1); } else { token = T_Double; goto normal_return; } } else { /* Default: Everything is a string */ yylval_was_set = TRUE; token = create_string_token(yytext); goto normal_return; } } /* * Either followedby is not FOLLBY_TOKEN or this lexeme is part * of a string. Hence, we need to return T_String. * * _Except_ we might have a -4 or -6 flag on a an association * configuration line (server, peer, pool, etc.). * * This is a terrible hack, but the grammar is ambiguous so we * don't have a choice. [SK] * * The ambiguity is in the keyword scanner, not ntp_parser.y. * We do not require server addresses be quoted in ntp.conf, * complicating the scanner's job. To avoid trying (and * failing) to match an IP address or DNS name to a keyword, * the association keywords use FOLLBY_STRING in the keyword * table, which tells the scanner to force the next token to be * a T_String, so it does not try to match a keyword but rather * expects a string when -4/-6 modifiers to server, peer, etc. * are encountered. * restrict -4 and restrict -6 parsing works correctly without * this hack, as restrict uses FOLLBY_TOKEN. [DH] */ if ('-' == yytext[0]) { if ('4' == yytext[1]) { token = T_Ipv4_flag; goto normal_return; } else if ('6' == yytext[1]) { token = T_Ipv6_flag; goto normal_return; } } instring = FALSE; if (FOLLBY_STRING == followedby) followedby = FOLLBY_TOKEN; yylval_was_set = TRUE; token = create_string_token(yytext); normal_return: if (T_EOC == token) DPRINTF(4,("\t<end of command>\n")); else DPRINTF(4, ("yylex: lexeme '%s' -> %s\n", yytext, token_name(token))); if (!yylval_was_set) yylval.Integer = token; return token; lex_too_long: yytext[min(sizeof(yytext) - 1, 50)] = 0; msyslog(LOG_ERR, "configuration item on line %d longer than limit of %lu, began with '%s'", lex_stack->curpos.nline, (u_long)min(sizeof(yytext) - 1, 50), yytext); /* * If we hit the length limit reading the startup configuration * file, abort. */ if (lex_from_file()) exit(sizeof(yytext) - 1); /* * If it's runtime configuration via ntpq :config treat it as * if the configuration text ended before the too-long lexeme, * hostname, or string. */ yylval.Integer = 0; return 0; }
/* * yylex() - function that does the actual scanning. * Bison expects this function to be called yylex and for it to take no * input and return an int. * Conceptually yylex "returns" yylval as well as the actual return * value representing the token or type. */ int yylex( void ) { size_t i; int instring = 0; int yylval_was_set = 0; int token; /* The return value/the recognized token */ int ch; static follby followedby = FOLLBY_TOKEN; do { /* Ignore whitespace at the beginning */ while (EOF != (ch = get_next_char()) && isspace(ch) && !is_EOC(ch)) ; /* Null Statement */ if (EOF == ch) { if (!input_from_file || !curr_include_level) return 0; FCLOSE(fp[curr_include_level]); ip_file = fp[--curr_include_level]; token = T_EOC; goto normal_return; } else if (is_EOC(ch)) { /* end FOLLBY_STRINGS_TO_EOC effect */ followedby = FOLLBY_TOKEN; token = T_EOC; goto normal_return; } else if (is_special(ch) && FOLLBY_TOKEN == followedby) { /* special chars are their own token values */ token = ch; /* * '=' implies a single string following as in: * setvar Owner = "The Boss" default * This could alternatively be handled by * removing '=' from special_chars and adding * it to the keyword table. */ if ('=' == ch) followedby = FOLLBY_STRING; yytext[0] = (char)ch; yytext[1] = '\0'; goto normal_return; } else push_back_char(ch); /* save the position of start of the token */ ip_file->prev_token_line_no = ip_file->line_no; ip_file->prev_token_col_no = ip_file->col_no; /* Read in the lexeme */ i = 0; while (EOF != (ch = get_next_char())) { yytext[i] = (char)ch; /* Break on whitespace or a special character */ if (isspace(ch) || is_EOC(ch) || '"' == ch || (FOLLBY_TOKEN == followedby && is_special(ch))) break; /* Read the rest of the line on reading a start of comment character */ if ('#' == ch) { while (EOF != (ch = get_next_char()) && '\n' != ch) ; /* Null Statement */ break; } i++; if (i >= COUNTOF(yytext)) goto lex_too_long; } /* Pick up all of the string inside between " marks, to * end of line. If we make it to EOL without a * terminating " assume it for them. * * XXX - HMS: I'm not sure we want to assume the closing " */ if ('"' == ch) { instring = 1; while (EOF != (ch = get_next_char()) && ch != '"' && ch != '\n') { yytext[i++] = (char)ch; if (i >= COUNTOF(yytext)) goto lex_too_long; } /* * yytext[i] will be pushed back as not part of * this lexeme, but any closing quote should * not be pushed back, so we read another char. */ if ('"' == ch) ch = get_next_char(); } /* Pushback the last character read that is not a part * of this lexeme. * If the last character read was an EOF, pushback a * newline character. This is to prevent a parse error * when there is no newline at the end of a file. */ if (EOF == ch) push_back_char('\n'); else push_back_char(ch); yytext[i] = '\0'; } while (i == 0); /* Now return the desired token */ /* First make sure that the parser is *not* expecting a string * as the next token (based on the previous token that was * returned) and that we haven't read a string. */ if (followedby == FOLLBY_TOKEN && !instring) { token = is_keyword(yytext, &followedby); if (token) goto normal_return; else if (is_integer(yytext)) { yylval_was_set = 1; errno = 0; if ((yylval.Integer = strtol(yytext, NULL, 10)) == 0 && ((errno == EINVAL) || (errno == ERANGE))) { msyslog(LOG_ERR, "Integer cannot be represented: %s", yytext); exit(1); } else { token = T_Integer; goto normal_return; } } else if (is_double(yytext)) { yylval_was_set = 1; errno = 0; if ((yylval.Double = atof(yytext)) == 0 && errno == ERANGE) { msyslog(LOG_ERR, "Double too large to represent: %s", yytext); exit(1); } else { token = T_Double; goto normal_return; } } else { /* Default: Everything is a string */ yylval_was_set = 1; token = create_string_token(yytext); goto normal_return; } } /* * Either followedby is not FOLLBY_TOKEN or this lexeme is part * of a string. Hence, we need to return T_String. * * _Except_ we might have a -4 or -6 flag on a an association * configuration line (server, peer, pool, etc.). * * This is a terrible hack, but the grammar is ambiguous so we * don't have a choice. [SK] * * The ambiguity is in the keyword scanner, not ntp_parser.y. * We do not require server addresses be quoted in ntp.conf, * complicating the scanner's job. To avoid trying (and * failing) to match an IP address or DNS name to a keyword, * the association keywords use FOLLBY_STRING in the keyword * table, which tells the scanner to force the next token to be * a T_String, so it does not try to match a keyword but rather * expects a string when -4/-6 modifiers to server, peer, etc. * are encountered. * restrict -4 and restrict -6 parsing works correctly without * this hack, as restrict uses FOLLBY_TOKEN. [DH] */ if ('-' == yytext[0]) { if ('4' == yytext[1]) { token = T_Ipv4_flag; goto normal_return; } else if ('6' == yytext[1]) { token = T_Ipv6_flag; goto normal_return; } } instring = 0; if (FOLLBY_STRING == followedby) followedby = FOLLBY_TOKEN; yylval_was_set = 1; token = create_string_token(yytext); normal_return: if (T_EOC == token) DPRINTF(4,("\t<end of command>\n")); else DPRINTF(4, ("yylex: lexeme '%s' -> %s\n", yytext, token_name(token))); if (!yylval_was_set) yylval.Integer = token; return token; lex_too_long: yytext[min(sizeof(yytext) - 1, 50)] = 0; msyslog(LOG_ERR, "configuration item on line %d longer than limit of %zu, began with '%s'", ip_file->line_no, sizeof(yytext) - 1, yytext); /* * If we hit the length limit reading the startup configuration * file, abort. */ if (input_from_file) exit(sizeof(yytext) - 1); /* * If it's runtime configuration via ntpq :config treat it as * if the configuration text ended before the too-long lexeme, * hostname, or string. */ yylval.Integer = 0; return 0; }
static int exfat_dir(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, const unsigned long int first_cluster, file_info_t *dir_list) { const struct exfat_dir_struct *ls=(const struct exfat_dir_struct*)dir_data->private_dir_data; const struct exfat_super_block*exfat_header=ls->boot_sector; const unsigned int cluster_shift=exfat_header->block_per_clus_bits + exfat_header->blocksize_bits; unsigned int cluster; unsigned char *buffer_dir=(unsigned char *)MALLOC(NBR_CLUSTER_MAX << cluster_shift); unsigned int nbr_cluster; const unsigned int total_clusters=le32(exfat_header->total_clusters); exfat_method_t exfat_meth=exFAT_FOLLOW_CLUSTER; int stop=0; const uint64_t start_exfat1=le32(exfat_header->fat_blocknr) << exfat_header->blocksize_bits; if(first_cluster<2) cluster=le32(exfat_header->rootdir_clusnr); else cluster=first_cluster; memset(buffer_dir, 0, NBR_CLUSTER_MAX<<cluster_shift); nbr_cluster=0; while(!is_EOC(cluster) && cluster>=2 && nbr_cluster<NBR_CLUSTER_MAX && stop==0) { if(exfat_read_cluster(disk, partition, exfat_header, buffer_dir + ((uint64_t) nbr_cluster << cluster_shift), cluster) != (1<<cluster_shift)) { log_error("exFAT: Can't read directory cluster.\n"); stop=1; } if(stop==0) { if(exfat_meth==exFAT_FOLLOW_CLUSTER) { const unsigned int next_cluster=exfat_get_next_cluster(disk, partition, start_exfat1, cluster); if((next_cluster>=2 && next_cluster<=total_clusters) || is_EOC(next_cluster)) cluster=next_cluster; else if(next_cluster==0) { #if 0 /* FIXME: experimental */ if(cluster==first_cluster && (dir_data->param & FLAG_LIST_DELETED)==FLAG_LIST_DELETED) exfat_meth=exFAT_NEXT_FREE_CLUSTER; /* Recovery of a deleted directory */ else cluster=0; /* Stop directory listing */ #else cluster=0; /* Stop directory listing */ #endif } else exfat_meth=exFAT_NEXT_CLUSTER; /* exFAT is corrupted, don't trust it */ } if(exfat_meth==exFAT_NEXT_CLUSTER) cluster++; else if(exfat_meth==exFAT_NEXT_FREE_CLUSTER) { /* Deleted directories are composed of "free" clusters */ #if 0 while(++cluster<total_clusters && exfat_get_next_cluster(disk, partition, start_exfat1, cluster)!=0); #endif } nbr_cluster++; } } if(nbr_cluster>0) dir_exfat_aux(buffer_dir, nbr_cluster<<cluster_shift, dir_data, dir_list); free(buffer_dir); return 0; }