void send_time(bool is_use_ssl,char *data) { time_t t; char *ti; char *res; char *nick; char *channel; nick=get_nick(data); channel=get_channel(data); t=time(NULL); ti=ctime(&t); if(channel == NULL) res=string_add("PRIVMSG %s :%s",nick,ti); else res=string_add("PRIVMSG %s :%s: %s",channel,nick,ti); free(nick); null_no_free(channel); if(is_use_ssl) SSL_write(ssl,res,strlen(res)); else send(sockfd,res,strlen(res),0); free(res); }
// receives a number, returns the current CPU use void send_cpu_response(struct hitArgs *args, char *path, char *request_body) { char tmp[4]; if (args->form_value_counter==1 && !strncmp(form_name(args, 0), "counter", strlen(form_name(args, 0)))) { STRING *response = new_string(32); string_add(response, "["); for (int p=0; p<max_cpu; p++) { sprintf(tmp, "%d", usages[p]); string_add(response, tmp); if (p < max_cpu-1) { string_add(response, ","); } } string_add(response, "]"); int c = atoi(form_value(args, 0)); if (c > max_cpu) c=0; // TODO: use c if needed ok_200(args, "\nContent-Type: application/json", string_chars(response), path); string_free(response); } else { forbidden_403(args, "Bad request"); } }
void ok_200(struct hitArgs *args, char *custom_headers, char *html, char *path) { STRING *headers = new_string(255); string_add(headers, "HTTP/1.1 200 OK\nServer: dweb\nCache-Control: no-cache\nPragma: no-cache"); if (custom_headers != NULL) { string_add(headers, custom_headers); } write_html(args->socketfd, string_chars(headers), html); string_free(headers); args->logger_function(LOG, "200 OK", path, args->socketfd); }
void send_data(int sockfd,SMBOT_CONF *conf) { char *nick; char *user; char *identify; char *join; char *buf; nick=string_add("NICK %s\n",conf->nick); user=string_add("USER %s %s %s :%s\n",conf->nick, conf->user_name,conf->server,conf->really_name); identify=string_add("PRIVMSG NickServ :IDENTIFY %s\n",conf->passwd); send(sockfd,nick,strlen(nick),0); send(sockfd,user,strlen(user),0); send(sockfd,identify,strlen(identify),0); free(nick); free(user); free(identify); while(buf=read_line(sockfd)) { printf("%s\n",buf); if(strstr(buf,"You are now identified for")) { free(buf); break; } if(strstr(buf,"Invalid password for")) { free(buf); printf("Invalid password!\n"); exit(-1); } free(buf); } if(buf == NULL) exit(-1); while(conf->channel->next != NULL) { conf->channel=conf->channel->next; join=string_add("JOIN %s\n",conf->channel->element); send(sockfd,join,strlen(join),0); free(join); } }
cStr *list_join(cList * list, cStr * sep) { Int size; cData *d; cStr *s; char *sp; /* figure up the size of the resulting string */ size = sep->len * (list->len - 1); for (d = list_first(list); d; d = list_next(list, d)) { /* just guess on its resulting size, magic numbers, whee */ if (d->type != STRING) size += 5; else size += d->u.str->len; } s = string_new(size); d = list_first(list); ADD_TOSTR()for (d = list_next(list, d); d; d = list_next(list, d)) { s = string_add(s, sep); ADD_TOSTR()} return s; }
// writes the given headers and sets the Content-Length void write_header(int socket_fd, char *head, long content_len) { STRING *header = new_string(255); string_add(header, head); string_add(header, "\nContent-Length: "); char cl[10]; // 100Mb = 104,857,600 bytes snprintf(cl, 10, "%ld", content_len); string_add(header, cl); string_add(header, "\r\n\r\n"); #ifndef SO_NOSIGPIPE send(socket_fd, string_chars(header), header->used_bytes-1, MSG_NOSIGNAL); #else write(socket_fd, string_chars(header), header->used_bytes-1); #endif string_free(header); }
int kpr_read_config(KPR *kpr) { FILE *kpr_fp; char name[1024]={0}; char path[1024]={0}; char arg[1024]={0}; KPR *node; kpr_fp=fopen(KPR_CONFIG_PATH,"rb"); if(kpr_fp == NULL) return -1; while(!feof(kpr_fp)) { fscanf(kpr_fp,"%s",name); fscanf(kpr_fp,"%s",path); fgets(arg,sizeof(arg)-1,kpr_fp); to_replace(name,sizeof(name)); to_replace(path,sizeof(path)); to_replace(arg,sizeof(arg)); if(name[0] == '\0' || path[0] == '\0' || arg[0] == '\0') continue; node=malloc(sizeof(KPR)); node->pid=-1; node->name=string_add("%s",name); node->path=string_add("%s",path); if(strcmp(arg,"NULL") == 0) node->arg=NULL; else node->arg=string_add("%s",arg); node->next=NULL; kpr->next=node; kpr=kpr->next; bzero(name,sizeof(name)); bzero(path,sizeof(path)); bzero(arg,sizeof(arg)); } fclose(kpr_fp); return 0; }
string_t * string_add_d(string_t *a1, string_t *a2) { string_t *sum; sum = string_add(a1, a2); string_free(a1); string_free(a2); return sum; }
void to_replace(char *res,int len) { char *temp; if(strstr(res,"\t")) { temp=string_add("%s",res); bzero(res,len); strreplace(temp,"\t","",res,len); free(temp); } if(strstr(res,"\n")) { temp=string_add("%s",res); bzero(res,len); strreplace(temp,"\n","",res,len); free(temp); } }
// receives a number, returns the current CPU temperature void send_temp_response(struct hitArgs *args, char *path, char *request_body) { char tmp[13]; STRING *response = new_string(32); if (temp >= 0) { sprintf(tmp, "%6.2f", temp); } else { sprintf(tmp, "?"); } string_add(response, tmp); ok_200(args, "\nContent-Type: text/plain", string_chars(response), path); string_free(response); }
void send_file_response(struct hitArgs *args, char *path, char *request_body, int path_length) { STRING *response = new_string(1024); string_add(response, "HTTP/1.1 200 OK\n"); string_add(response, "Connection: close\n"); string_add(response, "Content-Type: "); if (!strcmp(path, "") || path_ends_with(path, "index.html")) { string_add(response, "text/html"); write_header(args->socketfd, string_chars(response), index_html_len); write(args->socketfd, index_html, index_html_len); } else if (path_ends_with(path, "code.js")) { string_add(response, "text/javascript"); write_header(args->socketfd, string_chars(response), code_js_len); write(args->socketfd, code_js, code_js_len); } else if (path_ends_with(path, "jquery-2-1-0-min.js")) { string_add(response, "text/javascript"); write_header(args->socketfd, string_chars(response), jquery_2_1_0_min_js_len); write(args->socketfd, jquery_2_1_0_min_js, jquery_2_1_0_min_js_len); } else if (path_ends_with(path, "flot.js")) { string_add(response, "text/javascript"); write_header(args->socketfd, string_chars(response), flot_js_len); write(args->socketfd, flot_js, flot_js_len); } else { notfound_404(args, "no such file"); } string_free(response); // allow socket to drain before closing sleep(1); }
int main(void) { char str1[100] = {'\0'}; char str2[100] = {'\0'}; char str_result[200] = {'\0'}; int len1, len2, len3; printf("Please input the first string: "); scanf("%s", str1); printf("Please input the second string: "); scanf("%s", str2); len1 = strlen(str1); len2 = strlen(str2); string_add(len1, str1, len2, str2, str_result); len3 = strlen(str_result); reverse_string(len3, str_result); printf("\n %s add %s is equal to %s\n", str1, str2, str_result); return 0; }
int32_t main() { int32_t x; x = 1; int32_t y; int32_t temp_0 = 2 * x; int32_t temp_1 = temp_0 + 1; y = temp_1; int32_t z; char* label; char* temp_2 = initLabel(); char *temp_3 = (char *)malloc(5 + strlen(temp_2)); *((int*) temp_3) = strlen(temp_2); temp_3 += 4; strcpy(temp_3, temp_2); label = temp_3; int32_t* p; printf ("%d\n", globalInt); int32_t temp_4 = x * y; int32_t temp_5 = y + temp_4; int32_t* temp_6 = &globalInt; p = temp_6; int32_t temp_7 = fact(y, p); printf ("%d\n", temp_7); int32_t temp_8 = temp_5 + temp_7; z = temp_8; char *temp_9 = (char *)malloc(5 + strlen(" = ")); *((int*) temp_9) = strlen(" = "); temp_9 += 4; strcpy(temp_9, " = "); char* temp_10 = string_add(label, temp_9); char *temp_11 = (char *)malloc(5 + strlen(temp_10)); *((int*) temp_11) = strlen(temp_10); temp_11 += 4; strcpy(temp_11, temp_10); label = temp_11; char *temp_12 = (char *)malloc(5 + strlen("%s %d\n")); *((int*) temp_12) = strlen("%s %d\n"); temp_12 += 4; strcpy(temp_12, "%s %d\n"); char *temp_13 = (char *)malloc(5 + strlen(label)); *((int*) temp_13) = strlen(label); temp_13 += 4; strcpy(temp_13, label); int32_t temp_14 = printf(temp_12, temp_13, z); char *temp_15 = (char *)malloc(5 + strlen("The label '%s' has length %d\n")); *((int*) temp_15) = strlen("The label '%s' has length %d\n"); temp_15 += 4; strcpy(temp_15, "The label '%s' has length %d\n"); int32_t temp_16 = nstrlen(label); char *temp_17 = (char *)malloc(5 + strlen(label)); *((int*) temp_17) = strlen(label); temp_17 += 4; strcpy(temp_17, label); int32_t temp_18 = printf(temp_15, temp_17, temp_16); char *temp_19 = (char *)malloc(5 + strlen("globalInt = %d\n")); *((int*) temp_19) = strlen("globalInt = %d\n"); temp_19 += 4; strcpy(temp_19, "globalInt = %d\n"); int32_t temp_20 = printf(temp_19, *p); return 0; }
/** * Rewrite whole content of string to new value * * @param string pointer to string structure * @param text new content * @return new pointer to structure */ TString* string_rewrite( TString * string, char * text ) { string_clear( string ); return string_add( string, text ); }
Test(string_add, simple_line) { char *str = NULL; struct descriptor_data d = { .character = NULL, .str = &str, .max_str = 2048 }; char input_str[] = "Tell me what you want, what you really really want."; char expect_str[sizeof(input_str) + 3]; strcpy(expect_str, input_str); strcat(expect_str, "\n\r"); string_add(&d, input_str); cr_assert_str_eq(str, expect_str); cr_assert_eq(d.output.head, NULL); cr_assert(d.str); } Test(string_add, simple_line_no_menu) { char *str = NULL; struct descriptor_data d = { .character = NULL, .str = &str, .max_str = 2048, .connected = CON_EXDSCR, }; char input_str[] = "Tell me what you want, what you really really want."; char expect_str[sizeof(input_str) + 3]; strcpy(expect_str, input_str); strcat(expect_str, "\n\r"); string_add(&d, input_str); cr_assert_str_eq(str, expect_str); cr_assert_eq(d.output.head, NULL); cr_assert(d.str); } Test(string_add, line_with_terminator) { char *str = NULL; struct descriptor_data d = { .character = NULL, .str = &str, .max_str = 2048, }; char input_str[] = "Tell me what you want, what you really really want.@"; char expect_str[] = "Tell me what you want, what you really really want."; string_add(&d, input_str); cr_assert_str_eq(str, expect_str); cr_assert_eq(d.output.head, NULL); cr_assert(!d.str); } Test(string_add, menu_output) { char *str = NULL; struct descriptor_data d = { .character = NULL, .str = &str, .max_str = 2048, .connected = CON_EXDSCR, }; d.output.head = NULL; char input_str[] = "Tell me what you want, what you really really want.@"; char expect_str[] = "Tell me what you want, what you really really want."; string_add(&d, input_str); cr_assert_str_eq(str, expect_str); cr_assert_str_eq(d.output.head->text, MENU); cr_assert(!d.str); } Test(string_add, line_too_long) { char *str = NULL; struct descriptor_data d = { .character = NULL, .str = &str, .max_str = 20 }; char input_str[] = "Tell me what you want, what you really really want.@"; char expect_str[] = "Tell me what you wan"; string_add(&d, input_str); cr_assert_str_eq(str, expect_str); cr_assert_eq(d.output.head, NULL); cr_assert(!d.str); } Test(string_add, line_too_long_menu) { char *str = NULL; struct descriptor_data d = { .character = NULL, .str = &str, .max_str = 20, .connected = CON_EXDSCR, }; char input_str[] = "Tell me what you want, what you really really want.@"; char expect_str[] = "Tell me what you wan"; string_add(&d, input_str); cr_assert_str_eq(str, expect_str); cr_assert_str_eq(d.output.head->text, MENU); cr_assert(!d.str); } Test(string_add, append) { char *str = NULL; struct descriptor_data d = { .character = NULL, .str = &str, .max_str = 2048 }; str = malloc(128); strcpy(str, "Tell me what you want,"); char input_str[] = " what you really really want.@"; char expect_str[] = "Tell me what you want, what you really really want."; string_add(&d, input_str); cr_assert_str_eq(str, expect_str); cr_assert_eq(d.output.head, NULL); cr_assert(!d.str); } Test(string_add, append_menu) { char *str = NULL; struct descriptor_data d = { .character = NULL, .str = &str, .max_str = 2048, .connected = CON_EXDSCR, }; str = malloc(128); strcpy(str, "Tell me what you want,"); char input_str[] = " what you really really want.@"; char expect_str[] = "Tell me what you want, what you really really want."; string_add(&d, input_str); cr_assert_str_eq(str, expect_str); cr_assert_str_eq(d.output.head->text, MENU); cr_assert(!d.str); } Test(string_add_static, simple_line) { char str[2048] = {0}; struct descriptor_data d = { .character = NULL, .static_str = str, .max_str = sizeof(str) }; char input_str[] = "Tell me what you want, what you really really want."; char expect_str[sizeof(input_str) + 3]; strcpy(expect_str, input_str); strcat(expect_str, "\n\r"); string_add_static(&d, input_str); cr_assert_str_eq(str, expect_str); cr_assert_eq(d.output.head, NULL); cr_assert(d.static_str); } Test(string_add_static, simple_line_no_menu) { char str[2048] = {0}; struct descriptor_data d = { .character = NULL, .static_str = str, .max_str = sizeof(str), .connected = CON_EXDSCR, }; char input_str[] = "Tell me what you want, what you really really want."; char expect_str[sizeof(input_str) + 3]; strcpy(expect_str, input_str); strcat(expect_str, "\n\r"); string_add_static(&d, input_str); cr_assert_str_eq(str, expect_str); cr_assert_eq(d.output.head, NULL); cr_assert(d.static_str); } Test(string_add_static, line_with_terminator) { char str[2048] = {0}; struct descriptor_data d = { .character = NULL, .static_str = str, .max_str = sizeof(str), }; char input_str[] = "Tell me what you want, what you really really want.@"; char expect_str[] = "Tell me what you want, what you really really want."; string_add_static(&d, input_str); cr_assert_str_eq(str, expect_str); cr_assert_eq(d.output.head, NULL); cr_assert(!d.static_str); } Test(string_add_static, menu_output) { char str[2048] = {0}; struct descriptor_data d = { .character = NULL, .static_str = str, .max_str = sizeof(str), .connected = CON_EXDSCR, }; d.output.head = NULL; char input_str[] = "Tell me what you want, what you really really want.@"; char expect_str[] = "Tell me what you want, what you really really want."; string_add_static(&d, input_str); cr_assert_str_eq(str, expect_str); cr_assert_str_eq(d.output.head->text, MENU); cr_assert(!d.static_str); } Test(string_add_static, line_too_long) { char str[20] = {0}; struct descriptor_data d = { .character = NULL, .static_str = str, .max_str = sizeof(str), }; char input_str[] = "Tell me what you want, what you really really want.@"; char expect_str[] = "Tell me what you "; string_add_static(&d, input_str); cr_assert_str_eq(str, expect_str); cr_assert_eq(d.output.head, NULL); cr_assert(!d.static_str); } Test(string_add_static, line_too_long_menu) { char str[20] = {0}; struct descriptor_data d = { .character = NULL, .static_str = str, .max_str = sizeof(str), .connected = CON_EXDSCR, }; char input_str[] = "Tell me what you want, what you really really want.@"; char expect_str[] = "Tell me what you "; string_add_static(&d, input_str); cr_assert_str_eq(str, expect_str); cr_assert_str_eq(d.output.head->text, MENU); cr_assert(!d.static_str); } Test(string_add_static, append) { char str[2048] = {0}; struct descriptor_data d = { .character = NULL, .static_str = str, .max_str = sizeof(str), }; strcpy(str, "Tell me what you want,"); char input_str[] = " what you really really want.@"; char expect_str[] = "Tell me what you want, what you really really want."; string_add_static(&d, input_str); cr_assert_str_eq(str, expect_str); cr_assert_eq(d.output.head, NULL); cr_assert(!d.static_str); } Test(string_add_static, append_menu) { char str[2048] = {0}; struct descriptor_data d = { .character = NULL, .static_str = str, .max_str = sizeof(str), .connected = CON_EXDSCR, }; strcpy(str, "Tell me what you want,"); char input_str[] = " what you really really want.@"; char expect_str[] = "Tell me what you want, what you really really want."; string_add_static(&d, input_str); cr_assert_str_eq(str, expect_str); cr_assert_str_eq(d.output.head->text, MENU); cr_assert(!d.static_str); }
void webhit(struct hitArgs *args) { int j; http_verb type; long i, body_size = 0, request_size = 0, body_start, headers_end; char tmp_buf[READ_BUF_LEN+1]; char *body; struct http_header content_length; args->buffer = new_string(READ_BUF_LEN); // we need to read the HTTP headers first... // so loop until we receive "\r\n\r\n" while (get_body_start(string_chars(args->buffer)) < 0 && args->buffer->used_bytes <= MAX_INCOMING_REQUEST) { memset(tmp_buf, 0, READ_BUF_LEN+1); request_size += read(args->socketfd, tmp_buf, READ_BUF_LEN); string_add(args->buffer, tmp_buf); if (tmp_buf[0]==0) break; } if (request_size == 0) { finish_hit(args, 3); return; } content_length = get_header("Content-Length", string_chars(args->buffer)); args->content_length = atoi(content_length.value); body_start = get_body_start(string_chars(args->buffer)); headers_end = body_start-4; if (headers_end > 0) { args->headers = mallocx((int)headers_end+1); strncpy(args->headers, string_chars(args->buffer), headers_end); args->headers[headers_end]=0; } else { args->headers = mallocx(1); args->headers[0] = 0; } if (body_start >= 0) { body_size = request_size - body_start; } // safari seems to send the headers, and then the body slightly later while (body_size < args->content_length && args->buffer->used_bytes <= MAX_INCOMING_REQUEST) { memset(tmp_buf, 0, READ_BUF_LEN+1); i = read(args->socketfd, tmp_buf, READ_BUF_LEN); if (i>0) { request_size += i; string_add(args->buffer, tmp_buf); body_size = request_size - body_start; } else { // stop looping if we cannot read any more bytes break; } } if (request_size <= 0) { // cannot read request, so we'll stop forbidden_403(args, "failed to read http request"); finish_hit(args, 3); return; } args->logger_function(LOG, "request", string_chars(args->buffer), args->hit); if (type = request_type(string_chars(args->buffer)), type == HTTP_NOT_SUPPORTED) { forbidden_403(args, "Only simple GET and POST operations are supported"); finish_hit(args, 3); return; } // get a pointer to the request body (or NULL if it's not there) body = (type==HTTP_GET) ? NULL : args->buffer->ptr+get_body_start(string_chars(args->buffer)); // the request will be "GET [URL] " or "POST [URL] " followed by other details // we will terminate after the second space, to ignore everything else for (i = (type==HTTP_GET) ? 4 : 5; i < args->buffer->used_bytes; i++) { if (string_chars(args->buffer)[i] == ' ') { string_chars(args->buffer)[i] = 0; // second space, terminate string here break; } } j = (type==HTTP_GET) ? 4 : 5; // check for an absolute directory if (string_chars(args->buffer)[j+1] == '/') { forbidden_403(args, "Sorry, absolute paths are not permitted"); finish_hit(args, 3); return; } for (; j<i-1; j++) { // check for any parent directory use if (string_chars(args->buffer)[j] == '.' && string_chars(args->buffer)[j+1] == '.') { forbidden_403(args, "Sorry, parent paths (..) are not permitted"); finish_hit(args, 3); return; } } struct http_header ctype = get_header("Content-Type", args->headers); j = (int)strlen(ctype.value); if (j > 0) { args->content_type = mallocx(j+1); strncpy(args->content_type, ctype.value, j); if (string_matches_value(args->content_type, "application/x-www-form-urlencoded")) { get_form_values(args, body); } } else { args->content_type = mallocx(1); args->content_type[0] = 0; } // call the "responder function" which has been provided to do the rest args->responder_function(args, string_chars(args->buffer) + ((type==HTTP_GET) ? 5 : 6), body, type); finish_hit(args, 1); }
int main () { printf("%s\n\n", string_add("Hello ", "World")); return 0; }
static void phase3_get (token_ty *tp) { int c; int c2; int c_start; if (phase3_pushback_length) { *tp = phase3_pushback[--phase3_pushback_length]; return; } tp->string = NULL; for (;;) { tp->line_number = line_number; c = phase2_getc (); switch (c) { case EOF: tp->type = token_type_eof; return; case '\n': if (last_non_comment_line > last_comment_line) savable_comment_reset (); /* Intentionally not breaking. */ case ' ': case '\t': case '\f': continue; case '+': case '-': case '*': case '/': case '^': case '%': case '#': tp->type = token_type_operator1; return; case '<': case '>': case '=': c2 = phase1_getc (); if (c2 != '=') phase1_ungetc (c2); tp->type = token_type_operator2; return; case '~': c2 = phase1_getc (); if (c2 == '=') { tp->type = token_type_operator2; return; } else phase1_ungetc (c2); continue; case '(': tp->type = token_type_lparen; return; case ')': tp->type = token_type_rparen; return; case ',': tp->type = token_type_comma; return; case ';': tp->type = token_type_other; return; /* There are three operators beginning with a dot. '.', '..' and '...'. The most useful for us is the string concatenation operator ('..'). */ case '.': c = phase1_getc (); if (c == '.') { c = phase1_getc (); if (c == '.') { tp->type = token_type_other; return; } else { phase1_ungetc (c); tp->type = token_type_doubledot; return; } } else if (c >= '0' && c <= '9') { /* It's a number. We aren't interested in the actual numeric value, so ignore the dot and let next iteration eat the number. */ phase1_ungetc (c); continue; } else { phase1_ungetc (c); tp->type = token_type_dot; return; } case '"': case '\'': c_start = c; string_start (); for (;;) { /* We need unprocessed characters from phase 1. */ c = phase1_getc (); /* We got '\', this is probably an escape sequence. */ if (c == '\\') { c = phase1_getc (); switch (c) { case 'a': string_add ('\a'); break; case 'b': string_add ('\b'); break; case 'f': string_add ('\f'); break; case 'n': string_add ('\n'); break; case 'r': string_add ('\r'); break; case 't': string_add ('\t'); break; case 'v': string_add ('\v'); break; case 'x': { int num = 0; int i = 0; for (i = 0; i < 2; i++) { c = phase1_getc (); if (c >= '0' && c <= '9') num += c - '0'; else if (c >= 'a' && c <= 'f') num += c - 'a' + 10; else if (c >= 'A' && c <= 'F') num += c - 'A' + 10; else { phase1_ungetc (c); break; } if (i == 0) num *= 16; } if (i == 2) string_add (num); } break; case 'z': /* Ignore the following whitespace. */ do { c = phase1_getc (); } while (c == ' ' || c == '\n' || c == '\t' || c == '\r' || c == '\f' || c == '\v'); phase1_ungetc (c); break; default: /* Check if it's a '\ddd' sequence. */ if (c >= '0' && c <= '9') { int num = 0; int i = 0; while (c >= '0' && c <= '9' && i < 3) { num *= 10; num += (c - '0'); c = phase1_getc (); i++; } /* The last read character is either a non-number or another number after our '\ddd' sequence. We need to ungetc it. */ phase1_ungetc (c); /* The sequence number is too big, this causes a lexical error. Ignore it. */ if (num < 256) string_add (num); } else string_add (c); } } else if (c == c_start || c == EOF || c == '\n') { /* End of string. */ string_end (); tp->string = xstrdup (string_buf); tp->comment = add_reference (savable_comment); tp->type = token_type_string; return; } else string_add (c); } break; case '[': c = phase1_getc (); /* Count the number of equal signs. */ int esigns = 0; while (c == '=') { esigns++; c = phase1_getc (); } if (c != '[') { /* We did not find what we were looking for, ungetc it. */ phase1_ungetc (c); if (esigns == 0) { /* Our current character isn't '[' and we got 0 equal signs, so the first '[' must have been a left bracket. */ tp->type = token_type_lbracket; return; } else /* Lexical error, ignore it. */ continue; } string_start (); for (;;) { c = phase1_getc (); if (c == ']') { c = phase1_getc (); /* Count the number of equal signs. */ int esigns2 = 0; while (c == '=') { esigns2++; c = phase1_getc (); } if (c == ']' && esigns == esigns2) { /* We got ']==...==]', where the number of equal signs matches the number of equal signs in the opening bracket. */ string_end (); tp->string = xstrdup (string_buf); tp->comment = add_reference (savable_comment); tp->type = token_type_string; return; } else { /* Otherwise we got either ']==' garbage or ']==...==]' with a different number of equal signs. Add ']' and equal signs to the string, and ungetc the current character, because the second ']' might be a part of another closing long bracket, e.g. '==]===]'. */ phase1_ungetc (c); string_add (']'); while (esigns2--) string_add ('='); } } else { if (c == EOF) { string_end (); tp->string = xstrdup (string_buf); tp->comment = add_reference (savable_comment); tp->type = token_type_string; return; } else string_add (c); } } break; case ']': tp->type = token_type_rbracket; return; default: if (c >= '0' && c <= '9') { while (c >= '0' && c <= '9') c = phase1_getc (); if (c == '.') { c = phase1_getc (); while (c >= '0' && c <= '9') c = phase1_getc (); } if (c == 'e' || c == 'E') { if (c == '+' || c == '-') c = phase1_getc (); while (c >= '0' && c <= '9') c = phase1_getc (); } phase1_ungetc (c); tp->type = token_type_number; return; } else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_') { string_start (); while ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= '0' && c <= '9')) { string_add (c); c = phase1_getc (); } string_end (); phase1_ungetc (c); if (strcmp (string_buf, "not") == 0) tp->type = token_type_operator1; else if (strcmp (string_buf, "and") == 0) tp->type = token_type_operator2; else if (strcmp (string_buf, "or") == 0) tp->type = token_type_operator2; else { tp->string = xstrdup (string_buf); tp->type = token_type_symbol; } return; } else tp->type = token_type_other; } } }