initial commit

This commit is contained in:
Julian Daube 2018-04-13 09:47:22 +02:00
commit b0ab00efa8
3 changed files with 421 additions and 0 deletions

167
main.c Normal file
View File

@ -0,0 +1,167 @@
/*
* main.c
*
* Created on: 10.04.2018
* Author: julian
*/
#include <stdio.h>
#include "parser.h"
char buffer[100];
// Parser error handler
void error(const char * format, ...) {
fputs("ERR: ", stderr);
va_list list;
va_start(list, format);
vfprintf(stderr, format, list);
va_end(list);
notok = 1;
}
/** movement related stuff **/
enum movement_types {
MOVE_ABSOLUTE = 0,
MOVE_RELATIVE,
};
typedef struct coordinate_system {
float position[2];
enum movement_types movement_type;
} coordinate_system_t;
coordinate_system_t coordinate_system;
void move(const char * start, const char * end) {
argument_t arg;
float posa = 0, posb = 0;
static float feed = 100;
int count = 0;
// parse all arguments
while(nextArgument(&arg, &start, end)) {
switch(toUpper(arg.c)) {
case 'A':
posa = arg.num;
break;
case 'B':
posb = arg.num;
break;
case 'F':
if (arg.num <= 0) {
error("F%f: feed must be greater than zero!\n", arg.num);
return;
}
feed = arg.num;
break;
default:
continue;
}
count++;
}
if (!count) {
error("no arguments provided! need at least a new position for either A or B axis\n");
return;
}
printf("move A: %f, B: %f, feed %f\n", posa, posb, feed);
switch (coordinate_system.movement_type) {
case MOVE_RELATIVE:
coordinate_system.position[0] += posa;
coordinate_system.position[1] += posb;
break;
case MOVE_ABSOLUTE:
coordinate_system.position[0] = posa;
coordinate_system.position[1] = posb;
break;
}
}
void home(const char * start, const char * end) {
argument_t arg;
while(nextArgument(&arg, &start, end)) {
switch(toUpper(arg.c)) {
case 'A':
coordinate_system.position[0] = 0;
break;
case 'B':
coordinate_system.position[1] = 0;
break;
}
}
}
void state(const char * start, const char * end) {
printf("current position: A\t%f, B\t%f\n", coordinate_system.position[0], coordinate_system.position[1]);
}
/** Settings **/
void set_move_absolute() {
coordinate_system.movement_type = MOVE_ABSOLUTE;
}
void set_move_relative() {
coordinate_system.movement_type = MOVE_RELATIVE;
}
// reads one line of text in
// handles overflow
void readline(FILE * input) {
char * pos = buffer;
char * end = buffer + sizeof(buffer);
while(!feof(input)) {
char c = fgetc(input);
*pos = c;
pos++;
if (c == '\n') {
parse(buffer, pos);
pos = buffer;
}
if (pos >= end) {
printf("buffer overflow!");
pos = buffer;
}
}
}
#include <string.h>
int testAsFloat() {
float result = 0;
const char * str = "10";
const char * start = str, * end = str + strlen(str);
if (!asFloat(&result, &start, end)) return 0;
if (result < 9.999 || result > 10.001) return 0;
str = "0.001";
start = str, end = str + strlen(str);
if (!asFloat(&result, &start, end)) return 0;
if (result < 0.0005 || result > 0.0015) return 0;
return 1;
}
int main() {
printf("Test Float parsing: ");
if (testAsFloat()) {
printf(" PASS\n");
} else {
printf(" FAIL\n");
}
readline(stdin);
return 0;
}

198
parser.c Normal file
View File

@ -0,0 +1,198 @@
/*
* parser.c
*
* Created on: 10.04.2018
* Author: julian
*/
#include "parser.h"
#include <stdio.h>
int isWhite(char c) {
return c == ' ' || c == '\t' || c == '\r' || c == '\n';
}
int isNumber(char c) {
return c >= '0' && c <= '9';
}
// point that splits real numbers
int isPoint(char c) {
return c == '.' || c == ',';
}
char toLower(char in) {
if (in >= 'A' && in <= 'Z') {
return in - 'A' + 'a';
}
return in;
}
char toUpper(char in) {
if (in >= 'a' && in <= 'z') {
return in - 'a' + 'A';
}
return in;
}
void skipWhite(const char ** start, const char * end) {
if (!start) return;
while(*start < end && isWhite(**start)) {
++*start;
}
}
// returns 1 on success
int asInt(int * result, const char ** start, const char * end) {
if (!result || !start) return 0;
skipWhite(start, end);
if (*start == end) { return 0; }
int inv = 0;
unsigned int count = 0;
switch(**start) {
case '-':
inv = 1;
case '+':
++*start;
break;
}
*result = 0;
for(;*start != end && isNumber(**start); ++*start, count++) {
*result *= 10;
*result += **start - '0';
}
if (inv) {
*result = -*result;
}
return count > 0;
}
int asFloat(float *result, const char **start, const char * end) {
if (!result || !start ) return 0;
skipWhite(start, end);
if (*start == end) return 0;
int nominator = 0;
float denomiator = 0.f;
if (!asInt(&nominator, start, end)) return 0;
if (isPoint(**start)) {
const char * denom_end = *start +1;
while(denom_end < end && isNumber(*denom_end))
denom_end++;
while(--denom_end > *start) {
denomiator += *denom_end - '0';
denomiator /= 10.f;
}
}
*result = (float)(nominator) + denomiator;
return 1;
}
int nextArgument(argument_t* result, const char ** start, const char * end) {
if (!start | !result) return 0;
skipWhite(start, end);
if (*start == end) return 0;
result->c = **start;
++*start;
asFloat(&result->num, start, end);
return 1;
}
volatile int notok;
void gcode(const char * start, const char * end) {
int code;
skipWhite(&start, end);
if (start == end || !asInt(&code, &start, end)) {
error("expected number after G\n");
return;
}
switch(code) {
case 0:
case 1:
// move
move(start, end);
break;
case 28:
// home;
home(start, end);
break;
case 90:
set_move_absolute();
break;
case 91:
set_move_relative();
break;
default:
error("unknown gcode: %d\n",code);
}
}
void mcode(const char * start, const char * end) {
int code;
skipWhite(&start, end);
if (start == end || !asInt(&code, &start, end)) {
printf("expected number after M\n");
return;
}
switch(code) {
case 500:
// save config data
printf("save config data\n");
break;
case 502:
printf("restore default config\n");
break;
default:
error("no Mcode: %d\n", code);
}
}
void parse(const char * start, const char * end) {
notok = 0;
skipWhite(&start, end);
if (start == end) return;
switch (toLower(*start)) {
case 'g':
gcode(++start, end);
break;
case 'm':
mcode(++start, end);
break;
case '?':
state(++start, end);
return;
default:
error("expected g or m codes\n");
}
if (notok) { return; }
printf("ok\n");
}

56
parser.h Normal file
View File

@ -0,0 +1,56 @@
/*
* parser.h
*
* Created on: 10.04.2018
* Author: julian
*/
#ifndef PARSER_H_
#define PARSER_H_
#include <stdarg.h>
int isWhite(char c);
int isNumber(char c);
// point that splits real numbers
int isPoint(char c);
char toLower(char in);
char toUpper(char in);
void skipWhite(const char ** start, const char * end);
// returns 1 on success
int asInt(int * result, const char ** start, const char * end);
int asFloat(float *result, const char **start, const char * end);
typedef struct argument {
char c;
float num;
} argument_t;
int nextArgument(argument_t* result, const char ** start, const char * end);
extern volatile int notok;
void error(const char * format, ...);
/** system functions **/
void move(const char * start, const char * end);
void home(const char * start, const char * end);
void state(const char * start, const char * end);
void set_move_absolute();
void set_move_relative();
/** parser functions **/
void gcode(const char * start, const char * end);
void mcode(const char * start, const char * end);
void parse(const char * start, const char * end);
#endif /* PARSER_H_ */