static int inter_sscanf(int num_arg) { struct svalue *arg = sp - num_arg + 1; char *fmt, *in_string; int skip_it, number_of_matches = 0; if(arg[0].type != T_STRING) bad_arg(1, F_SSCANF); in_string = arg[0].u.string; if(in_string == 0) return 0; if(arg[1].type != T_STRING) bad_arg(2, F_SSCANF); fmt = arg[1].u.string; for(num_arg -= 2, arg += 2; num_arg >= 0; number_of_matches++, num_arg--, arg++) { char *next_percent; int i, type; for(; fmt[0] && fmt[0] != '%'; fmt++, in_string++) { if(in_string[0] == '\0' || fmt[0] != in_string[0]) return number_of_matches; if(fmt[1] == '%' && fmt[2] == '%') { if(in_string[1] != '%') return number_of_matches; fmt += 2; in_string++; } } if(fmt[0] == '\0') { if(in_string[0] && num_arg > 0) { free_svalue(arg->u.lvalue); arg->u.lvalue->type = T_STRING; arg->u.lvalue->u.string = string_copy(in_string); arg->u.lvalue->string_type = STRING_MALLOC; number_of_matches++; } break; } #ifdef DEBUG if(fmt[0] != '%') fatal("Should be a %% now !\n"); #endif fmt++; skip_it = 0; if(fmt[0] == '*') { skip_it = 1; fmt++; } if(!skip_it && num_arg < 1) error("Too few variables to sscanf()."); /* Maybe continue; */ type = T_STRING; if(fmt[0] == 'd') type = T_NUMBER; else if (fmt[0] != 's') error("Bad type : '%%%c' in sscanf fmt string.", fmt[0]); fmt++; if(type == T_NUMBER) { char *tmp = in_string; int tmp_num; tmp_num = (int) strtol(in_string, &in_string, 10); if(tmp == in_string) break; if(!skip_it) { free_svalue(arg->u.lvalue); arg->u.lvalue->type = T_NUMBER; arg->u.lvalue->u.number = tmp_num; } else { arg--; num_arg++; } continue; } if(fmt[0] == '%') error("Illegal to have 2 adjacent %'s in fmt string in sscanf."); if(fmt[0] == '\0') { if(!skip_it) { free_svalue(arg->u.lvalue); arg->u.lvalue->type = T_STRING; arg->u.lvalue->u.string = string_copy(in_string); arg->u.lvalue->string_type = STRING_MALLOC; } number_of_matches++; break; } if((next_percent = strchr(fmt, '%')) == NULL) next_percent = fmt + strlen(fmt); for(i = 0; in_string[i]; i++) { if(strncmp(in_string + i, fmt, next_percent - fmt) == 0) { char *match; if(!skip_it) { match = xalloc(i + 1); (void) strncpy(match, in_string, i); match[i] = '\0'; free_svalue(arg->u.lvalue); arg->u.lvalue->type = T_STRING; arg->u.lvalue->u.string = match; arg->u.lvalue->string_type = STRING_MALLOC; } else { arg--; num_arg++; } in_string += i + next_percent - fmt; fmt = next_percent; break; } } if(fmt != next_percent) break; } return number_of_matches; }