diff --git a/app/Http/Controllers/TableController.php b/app/Http/Controllers/TableController.php index 34f36f6..2429ffa 100644 --- a/app/Http/Controllers/TableController.php +++ b/app/Http/Controllers/TableController.php @@ -9,6 +9,7 @@ use App\Models\User; use App\Tables\Column; use App\Tables\CStructArrayExporter; use App\Tables\CsvExporter; +use App\Tables\CXMacroExporter; use App\Tables\JsonExporter; use App\Tables\PhpExporter; use Illuminate\Http\Request; @@ -289,6 +290,11 @@ class TableController extends Controller $exporter = new CStructArrayExporter($tableModel); break; + case 'xmacro': + $noq = explode(',', $request->input('noq','')); + $exporter = (new CXMacroExporter($tableModel))->noQuotesAround($noq); + break; + case 'php': $exporter = new PhpExporter($tableModel); break; diff --git a/app/Tables/CStructArrayExporter.php b/app/Tables/CStructArrayExporter.php index ce130d4..282a0f9 100644 --- a/app/Tables/CStructArrayExporter.php +++ b/app/Tables/CStructArrayExporter.php @@ -22,7 +22,7 @@ class CStructArrayExporter extends BaseExporter return 'c'; } - private function cify($name) + protected function cify($name) { $name = preg_replace('/[^a-z0-9_]/i', '_', $name); if (ctype_digit($name[0])) { @@ -79,49 +79,60 @@ class CStructArrayExporter extends BaseExporter } echo " { "; + $this->dumpRow($fields, $row); + echo " }"; + } + + echo "\n};\n"; + } - $firstf = true; - foreach ($fields as $field) { - if ($firstf) { - $firstf = false; - } else { + protected function dumpRow($fields, $row, $noQuoteCols=[], $spaces = true) + { + $firstf = true; + foreach ($fields as $field) { + if ($firstf) { + $firstf = false; + } else { + if ($spaces) echo ", "; - } - - $val = 0; - switch ($field->type) { - case 'string': - $val = ""; - break; - - case 'bool': - $val = false; - break; - } - - if (isset($row->{$field->name})) { - $val = $row->{$field->name}; - } - - // export to C format - switch ($field->type) { - case 'string': - echo '"' . addcslashes($val, "\0..\37!@\@\177..\377") . '"'; - break; + else + echo ","; + } - case 'bool': - echo (int)$val; - break; + $val = 0; + switch ($field->type) { + case 'string': + $val = ""; + break; - case 'int': - case 'float': + case 'bool': + $val = false; + break; + } + + if (isset($row->{$field->name})) { + $val = $row->{$field->name}; + } + + // export to C format + switch ($field->type) { + case 'string': + if (in_array($field->name, $noQuoteCols)) { echo $val; - break; - } + } else { + echo '"' . addcslashes($val, "\0..\37!@\@\177..\377") . '"'; + } + break; + + case 'bool': + echo (int)$val; + break; + + case 'int': + case 'float': + echo $val; + break; } - echo " }"; } - - echo "\n};\n"; } } diff --git a/app/Tables/CXMacroExporter.php b/app/Tables/CXMacroExporter.php new file mode 100644 index 0000000..e6e7ed5 --- /dev/null +++ b/app/Tables/CXMacroExporter.php @@ -0,0 +1,84 @@ +noQuoteCols = $cols; + return $this; + } + + /** + * @return string - mime type for the downloaded file + */ + protected function getMimeType() + { + return $this->wantDownload ? 'text/x-chdr' : 'text/plain'; + } + + /** + * @return string - file extension for the downloaded file + */ + protected function getFileExtension() + { + return 'h'; + } + + /** + * Write the document to stdout ('php://output') + */ + protected function writeDocument() + { + $table = $this->table; + + $any_bool = false; + $colnames = []; + $fields = array_map(function (Column $c) use (&$any_bool, &$colnames) { + if ($c->type == 'bool') $any_bool = true; + $cname = $this->cify($c->name); + $colnames[] = $cname; + return (object)['name' => $c->name, 'type' => $c->type, 'cname' => $cname]; + }, $this->columns); + + $ctablename = 'X_' .strtoupper($this->cify($table->name)); + + echo "#ifndef {$ctablename}_H\n". + "#define {$ctablename}_H\n\n"; + + echo "/*\n" . $this->getHeaderComment(' ') . "\n"; + + echo + " Example X macro processing the table: \n". + " \n"; + echo " #undef X\n"; + echo " #define X(".implode(', ', $colnames) .") \\\n". + " ...do something with the args\n". + " \n". + " Then run it by putting $ctablename somewhere in your C or H file.\n"; + echo "*/\n\n"; + + // Now the table itself + echo "#define ".$ctablename." \\\n"; + + $first = true; + foreach ($this->iterateRows() as $row) { + if ($first) { + $first = false; + } else { + echo " \\\n"; + } + + echo " X("; + $this->dumpRow($fields, $row, $this->noQuoteCols, false); + echo ")"; + } + + echo "\n\n#endif /* {$ctablename}_H */\n"; + } +} diff --git a/resources/views/table/_panel-export.blade.php b/resources/views/table/_panel-export.blade.php index 99cdac1..30de8fd 100644 --- a/resources/views/table/_panel-export.blade.php +++ b/resources/views/table/_panel-export.blade.php @@ -8,6 +8,7 @@ 'csv' => 'CSV table', 'csv-tab' => 'CSV table, tabbed', 'c' => 'C structs array', + 'xmacro' => 'C X Macro', ] as $type => $title)